ECHO is a system of R scripts and functions for quantifying the
nutrients sources and their transport in catchments of different scales.
Main sources are:
- ANIMO model, Outflow of agriculture and nature area
- Emission Registration (Industry, Atmospheric deposition, Other
agriculture, Water treatment plants, Others) ER
- Foreign rivers/streams RWS
- Load packages, constants and functions
pacman::p_load("tidyverse", "sf", "RODBC", "lubridate")
- Settings and functions
source("Directories.R")
source("Functions.R")
source("Constants.R")
- load STONE shape files: 538 catchments (ha), and merge with stone
plot numbers
Catchment <- read_csv(CSV_Catchment, show_col_types = FALSE) %>%
rename(ID = 1, Water_Body = 2, Area_Catchment = 3)
Catchment
- Prepare fundamental data frame
Catchment_Time <- tibble(ID = rep(1:NoC, each = length(YoI) * 12), Year = rep(rep(YoI, each = 12), NoC), Month = rep(1:12, NoC * length(YoI)))
Catchment_Time
- Catchment ID vs Stone plot number, with plot area
Catchment_Plot <- as.data.frame(read_delim(TXT_Catchment_Plot, show_col_types = FALSE)) %>%
rename(ID = 1, Plot = 2, Area_Plot = 3)
Catchment_Plot
- load STONE output data, years of interest, P(kg/m2/decade),
N(kg/m2/decade)
Stone <- read_csv(CSV_Stone, show_col_types = FALSE)
Stone
#—————————————————————————————————————— # N (kg) # Monthly
Stone_N_Monthly <- Stone %>%
select(Plot, Year, Month, N) %>%
group_by(Plot, Year, Month) %>%
summarise(N = sum(N, na.rm = TRUE), .groups = "drop") %>%
right_join(Catchment_Plot, by = "Plot") %>%
mutate(N = Area_Plot * N) %>%
group_by(ID, Year, Month) %>%
summarise(Stone_N = sum(N, na.rm = TRUE), .groups = "drop")
Stone_N_Monthly <- left_join(Catchment_Time, Stone_N_Monthly, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
write.csv(Stone_N_Monthly, file = "../Results/Stone_N_Monthly.csv", row.names = FALSE)
#————————- # Yearly
Stone_N_Yearly <- Stone_N_Monthly %>%
group_by(ID, Year) %>%
summarise(Stone_N = sum(Stone_N, na.rm = TRUE), .groups = "drop")
write.csv(Stone_N_Yearly, file = "../Results/Stone_N_Yearly.csv", row.names = FALSE)
#——————————————————————————– # P (kg) # Monthly
Stone_P_Monthly <- Stone %>%
select(Plot, Year, Month, P) %>%
group_by(Plot, Year, Month) %>%
summarise(P = sum(P, na.rm = TRUE), .groups = "drop") %>%
right_join(Catchment_Plot, by = "Plot") %>%
mutate(P = Area_Plot * P) %>%
group_by(ID, Year, Month) %>%
summarise(Stone_P = sum(P, na.rm = TRUE), .groups = "drop")
Stone_P_Monthly <- left_join(Catchment_Time, Stone_P_Monthly, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
write.csv(Stone_P_Monthly, file = "../Results/Stone_P_Monthly.csv", row.names = FALSE)
#————————- # Yearly
Stone_P_Yearly <- Stone_P_Monthly %>%
group_by(ID, Year) %>%
summarise(Stone_P = sum(Stone_P, na.rm = TRUE), .groups = "drop")
write.csv(Stone_P_Yearly, file = "../Results/Stone_P_Yearly.csv", row.names = FALSE)
Emission from Emission Registration (ER) for open water, kg
N total (303), P total (302), Q(85)
load Catchment-ER matching file (538 catchments overlay with
gaf90)
Catchment_ER <- read_csv(CSV_ER, show_col_types = FALSE)
Emissions, with AI code
ER_N <- read_csv(CSV_ER_N, show_col_types = FALSE)
ER_P <- read_csv(CSV_ER_P, show_col_types = FALSE)
#——————————————————————————————– # RWZI
RWZI_Catchment_AI <- read_csv(CSV_RWZI_Catchment, show_col_types = FALSE)
N
RWZI_N_Yearly <- filter(ER_N, Group == "RWZI", !is.na(Emission)) %>%
left_join(RWZI_Catchment_AI, by = "AI_code") %>%
group_by(ID, Year) %>%
summarise(RWZI_N = sum(Emission, na.rm = TRUE), .groups = "drop") %>%
spread(Year, RWZI_N) %>%
pivot_longer(cols = 2:11, names_to ="Year", values_to = "RWZI_N") %>%
group_by(ID) %>%
mutate(RWZI_N = ifelse(is.na(RWZI_N), mean(RWZI_N, na.rm = TRUE), RWZI_N))
write.csv(RWZI_N_Yearly, file = "../Results/RWZI_N_Yearly.csv", row.names = FALSE)
RWZI_N_Yearly$Year <- as.numeric(RWZI_N_Yearly$Year)
RWZI_N_Monthly <- mutate(RWZI_N_Yearly, RWZI_N = RWZI_N/12)
RWZI_N_Monthly <- left_join(Catchment_Time, RWZI_N_Monthly, by = c("ID", "Year")) %>%
replace(is.na(.), 0.0)
write.csv(RWZI_N_Monthly, file = "../Results/RWZI_N_Monthly.csv", row.names = FALSE)
P
RWZI_P_Yearly <- filter(ER_P, Group == "RWZI", !is.na(Emission)) %>%
left_join(RWZI_Catchment_AI, by = "AI_code") %>%
group_by(ID, Year) %>%
summarise(RWZI_P = sum(Emission, na.rm = TRUE), .groups = "drop") %>%
spread(Year, RWZI_P) %>%
pivot_longer(cols = 2:11, names_to ="Year", values_to = "RWZI_P") %>%
group_by(ID) %>%
mutate(RWZI_P = ifelse(is.na(RWZI_P), mean(RWZI_P, na.rm = TRUE), RWZI_P))
write.csv(RWZI_P_Yearly, file = "../Results/RWZI_P_Yearly.csv", row.names = FALSE)
RWZI_P_Yearly$Year <- as.numeric(RWZI_P_Yearly$Year)
RWZI_P_Monthly <- mutate(RWZI_P_Yearly, RWZI_P = RWZI_P/12)
RWZI_P_Monthly <- left_join(Catchment_Time, RWZI_P_Monthly, by = c("ID", "Year")) %>%
replace(is.na(.), 0.0)
write.csv(RWZI_P_Monthly, file = "../Results/RWZI_P_Monthly.csv", row.names = FALSE)
#——————————————————————————————– # # Overige landbouweemissies #
N
LO_N_Yearly <- filter(ER_N, Group == "LO", !is.na(Emission)) %>%
left_join(Catchment_ER, by = "AI_code") %>%
group_by(ID, Year) %>%
summarise(LO_N = sum(Emission, na.rm = TRUE), .groups = "drop") %>%
spread(Year, LO_N) %>%
pivot_longer(cols = 2:11, names_to ="Year", values_to = "LO_N") %>%
group_by(ID) %>%
mutate(LO_N = ifelse(is.na(LO_N), mean(LO_N, na.rm = TRUE), LO_N))
write.csv(LO_N_Yearly, file = "../Results/LO_N_Yearly.csv", row.names = FALSE)
LO_N_Yearly$Year <- as.numeric(LO_N_Yearly$Year)
LO_N_Monthly <- mutate(LO_N_Yearly, LO_N = LO_N/12)
LO_N_Monthly <- left_join(Catchment_Time, LO_N_Monthly, by = c("ID", "Year")) %>%
replace(is.na(.), 0.0)
write.csv(LO_N_Monthly, file = "../Results/LO_N_Monthly.csv", row.names = FALSE)
Industry
IN_N_Yearly <- filter(ER_N, Group == "IN", !is.na(Emission)) %>%
left_join(Catchment_ER, by = "AI_code") %>%
group_by(ID, Year) %>%
summarise(IN_N = sum(Emission, na.rm = TRUE), .groups = "drop") %>%
spread(Year, IN_N) %>%
pivot_longer(cols = 2:11, names_to ="Year", values_to = "IN_N") %>%
group_by(ID) %>%
mutate(IN_N = ifelse(is.na(IN_N), mean(IN_N, na.rm = TRUE), IN_N))
write.csv(IN_N_Yearly, file = "../Results/IN_N_Yearly.csv", row.names = FALSE)
IN_N_Yearly$Year <- as.numeric(IN_N_Yearly$Year)
IN_N_Monthly <- mutate(IN_N_Yearly, IN_N = IN_N/12)
IN_N_Monthly <- left_join(Catchment_Time, IN_N_Monthly, by = c("ID", "Year")) %>%
replace(is.na(.), 0.0)
write.csv(IN_N_Monthly, file = "../Results/IN_N_Monthly.csv", row.names = FALSE)
Atmosf deposition
DW_N_Yearly <- filter(ER_N, Group == "DW", !is.na(Emission)) %>%
left_join(Catchment_ER, by = "AI_code") %>%
group_by(ID, Year) %>%
summarise(DW_N = sum(Emission, na.rm = TRUE), .groups = "drop") %>%
spread(Year, DW_N) %>%
drop_na() %>%
add_column("2012" = NA, .after = "2010") %>%
add_column("2011" = NA, .after = "2010") %>%
pivot_longer(cols = 2:11, names_to ="Year", values_to = "DW_N") %>%
group_by(ID) %>%
mutate(DW_N = ifelse(is.na(DW_N), mean(DW_N, na.rm = TRUE), DW_N))
write.csv(DW_N_Yearly, file = "../Results/DW_N_Yearly.csv", row.names = FALSE)
DW_N_Yearly$Year <- as.numeric(DW_N_Yearly$Year)
DW_N_Monthly <- mutate(DW_N_Yearly, DW_N = DW_N/12)
DW_N_Monthly <- left_join(Catchment_Time, DW_N_Monthly, by = c("ID", "Year")) %>%
replace(is.na(.), 0.0)
write.csv(DW_N_Monthly, file = "../Results/DW_N_Monthly.csv", row.names = FALSE)
Overige
OR_N_Yearly <- filter(ER_N, Group == "OR", !is.na(Emission)) %>%
left_join(Catchment_ER, by = "AI_code") %>%
group_by(ID, Year) %>%
summarise(OR_N = sum(Emission, na.rm = TRUE), .groups = "drop") %>%
spread(Year, OR_N) %>%
pivot_longer(cols = 2:11, names_to ="Year", values_to = "OR_N") %>%
group_by(ID) %>%
mutate(OR_N = ifelse(is.na(OR_N), mean(OR_N, na.rm = TRUE), OR_N))
write.csv(OR_N_Yearly, file = "../Results/OR_N_Yearly.csv", row.names = FALSE)
OR_N_Yearly$Year <- as.numeric(OR_N_Yearly$Year)
OR_N_Monthly <- mutate(OR_N_Yearly, OR_N = OR_N/12)
OR_N_Monthly <- left_join(Catchment_Time, OR_N_Monthly, by = c("ID", "Year")) %>%
replace(is.na(.), 0.0)
write.csv(OR_N_Monthly, file = "../Results/OR_N_Monthly.csv", row.names = FALSE)
#—————————————————————————– # # Overige landbouweemissies # P
LO_P_Yearly <- filter(ER_P, Group == "LO", !is.na(Emission)) %>%
left_join(Catchment_ER, by = "AI_code") %>%
group_by(ID, Year) %>%
summarise(LO_P = sum(Emission, na.rm = TRUE), .groups = "drop") %>%
spread(Year, LO_P) %>%
pivot_longer(cols = 2:11, names_to ="Year", values_to = "LO_P") %>%
group_by(ID) %>%
mutate(LO_P = ifelse(is.na(LO_P), mean(LO_P, na.rm = TRUE), LO_P))
write.csv(LO_P_Yearly, file = "../Results/LO_P_Yearly.csv", row.names = FALSE)
LO_P_Yearly$Year <- as.numeric(LO_P_Yearly$Year)
LO_P_Monthly <- mutate(LO_P_Yearly, LO_P = LO_P/12)
LO_P_Monthly <- left_join(Catchment_Time, LO_P_Monthly, by = c("ID", "Year")) %>%
replace(is.na(.), 0.0)
write.csv(LO_P_Monthly, file = "../Results/LO_P_Monthly.csv", row.names = FALSE)
Industry
IN_P_Yearly <- filter(ER_P, Group == "IN", !is.na(Emission)) %>%
left_join(Catchment_ER, by = "AI_code") %>%
group_by(ID, Year) %>%
summarise(IN_P = sum(Emission, na.rm = TRUE), .groups = "drop") %>%
spread(Year, IN_P) %>%
pivot_longer(cols = 2:11, names_to ="Year", values_to = "IN_P") %>%
group_by(ID) %>%
mutate(IN_P = ifelse(is.na(IN_P), mean(IN_P, na.rm = TRUE), IN_P))
write.csv(IN_P_Yearly, file = "../Results/IN_P_Yearly.csv", row.names = FALSE)
IN_P_Yearly$Year <- as.numeric(IN_P_Yearly$Year)
IN_P_Monthly <- mutate(IN_P_Yearly, IN_P = IN_P/12)
IN_P_Monthly <- left_join(Catchment_Time, IN_P_Monthly, by = c("ID", "Year")) %>%
replace(is.na(.), 0.0)
write.csv(IN_P_Monthly, file = "../Results/IN_P_Monthly.csv", row.names = FALSE)
Overige
OR_P_Yearly <- filter(ER_P, Group == "OR", !is.na(Emission)) %>%
left_join(Catchment_ER, by = "AI_code") %>%
group_by(ID, Year) %>%
summarise(OR_P = sum(Emission, na.rm = TRUE), .groups = "drop") %>%
spread(Year, OR_P) %>%
pivot_longer(cols = 2:11, names_to ="Year", values_to = "OR_P") %>%
group_by(ID) %>%
mutate(OR_P = ifelse(is.na(OR_P), mean(OR_P, na.rm = TRUE), OR_P))
write.csv(OR_P_Yearly, file = "../Results/OR_P_Yearly.csv", row.names = FALSE)
OR_P_Yearly$Year <- as.numeric(OR_P_Yearly$Year)
OR_P_Monthly <- mutate(OR_P_Yearly, OR_P = OR_P/12)
OR_P_Monthly <- left_join(Catchment_Time, OR_P_Monthly, by = c("ID", "Year")) %>%
replace(is.na(.), 0.0)
write.csv(OR_P_Monthly, file = "../Results/OR_P_Monthly.csv", row.names = FALSE)
#———————————————————————————————————————————————————– # 9. Incoming
and Discharge # Big rivers
#———————————————————————————————————————————————————– # Inlet and
Discharge Q, m3/s
In_Out_let_Q <- read_csv(CSV_In_Out_Q, show_col_types = FALSE)
#—————————— # Inlet Q
Inlet_Q_Monthly <- In_Out_let_Q %>%
filter(Location %in% c("EIJSDGS", "LOBH", "SCHAARVODDL"), Year %in% YoI) %>%
group_by(Location, Year, Month) %>%
summarise(Q = mean(Q, na.rm = TRUE), .groups = "drop") %>%
mutate(Days = days_in_month(as.Date(paste(Year, Month,"01", sep = "-"))), Discharge = Q * Days * 86400) %>%
select(Location, Year, Month, Discharge)
#———————————————————————————————————————————————————– # N,P, mg/l
In_Out_NP <- read_csv(CSV_In_Out_NP, show_col_types = FALSE)
#—————————— # Incoming N
Inlet_N_Monthly <- In_Out_NP %>%
select(Location, Day, Month, Year, Parameter, Measurement) %>%
filter(Parameter %in% c("stikstof Kjeldahl", "nitraat", "nitriet"), Location %in% c("EIJSDPTN", "LOBPTN", "SCHAARVODDL"), Year %in% YoI) %>%
spread(Parameter, Measurement) %>%
rename(NO2 = "nitriet", NO3 = "nitraat", NKj = "stikstof Kjeldahl") %>%
group_by(Location, Year, Month) %>%
summarise(across(c(NO2, NO3, NKj), mean, na.rm = TRUE), .groups = "drop") %>%
mutate(Inlet_N = 0.001 * (NKj + NO3 + NO2) * Inlet_Q_Monthly$Discharge) %>%
select(Location, Year, Month, Inlet_N)
Inlet_Lobptn1 <- filter(Inlet_N_Monthly, Location == "LOBPTN") %>%
mutate(Location = "LOBPTN1", Inlet_N = Inlet_N * 0.15)
Inlet_Lobptn2 <- filter(Inlet_N_Monthly, Location == "LOBPTN") %>%
mutate(Location = "LOBPTN2", Inlet_N = Inlet_N * 0.85)
Inlet_N_Monthly <- filter(Inlet_N_Monthly, !Location == "LOBPTN") %>%
bind_rows(Inlet_Lobptn1, Inlet_Lobptn2) %>%
mutate(ID = case_when(Location == "LOBPTN1" ~ 1002,
Location == "LOBPTN2" ~ 1004,
Location == "EIJSDPTN" ~ 1001,
Location == "SCHAARVODDL" ~ 1003))
write.csv(Inlet_N_Monthly, file = "../Results/Inlet_BigRivers_N_Monthly.csv", row.names = FALSE)
Inlet_N_Yearly <- Inlet_N_Monthly %>%
group_by(ID, Year) %>%
summarise(Inlet_N = sum(Inlet_N, na.rm = TRUE), .groups = "drop")
write.csv(Inlet_N_Yearly, file = "../Results/Inlet_BigRivers_N_Yearly.csv", row.names = FALSE)
#—————————— # Incoming P
Inlet_P_Monthly <- In_Out_NP %>%
select(Location, Day, Month, Year, Parameter, Measurement) %>%
filter(Parameter == "fosfor totaal", Location %in% c("EIJSDPTN", "LOBPTN", "SCHAARVODDL"), Year %in% YoI) %>%
group_by(Location, Year, Month) %>%
summarise(Inlet_P = mean(Measurement, na.rm = TRUE), .groups = "drop") %>%
mutate(Inlet_P = 0.001 * Inlet_P * Inlet_Q_Monthly$Discharge) %>%
select(Location, Year, Month, Inlet_P)
write.csv(Inlet_P_Monthly, file = "../Results/Inlet_BigRivers_P_Monthly.csv", row.names = FALSE)
Inlet_Lobptn1 <- filter(Inlet_P_Monthly, Location == "LOBPTN") %>%
mutate(Location = "LOBPTN1", Inlet_P = Inlet_P * 0.15)
Inlet_Lobptn2 <- filter(Inlet_P_Monthly, Location == "LOBPTN") %>%
mutate(Location = "LOBPTN2", Inlet_P = Inlet_P * 0.85)
Inlet_P_Monthly <- filter(Inlet_P_Monthly, !Location == "LOBPTN") %>%
bind_rows(Inlet_Lobptn1, Inlet_Lobptn2) %>%
mutate(ID = case_when(Location == "LOBPTN1" ~ 1002,
Location == "LOBPTN2" ~ 1004,
Location == "EIJSDPTN" ~ 1001,
Location == "SCHAARVODDL" ~ 1003))
write.csv(Inlet_P_Monthly, file = "../Results/Inlet_BigRivers_P_Monthly.csv", row.names = FALSE)
Inlet_P_Yearly <- Inlet_P_Monthly %>%
group_by(ID, Year) %>%
summarise(Inlet_P = sum(Inlet_P, na.rm = TRUE), .groups = "drop")
write.csv(Inlet_P_Yearly, file = "../Results/Inlet_BigRivers_P_Yearly.csv", row.names = FALSE)
———————————————————————————————————————
small streams from neibouring countries
———————————————————————————————————————
Catchment_buitenland <- read_csv(CSV_Catchment_buitenland, show_col_types = FALSE) %>%
filter(str_detect(inlaat, "Buitenland"), !str_detect(debiet, "op basis van vrachtbepaling")) %>%
select(ID, debiet, kwaliteit)
IN_buitenland_Q_Monthly <- read_csv(CSV_IN_buitenland_Q_mean, show_col_types = FALSE) %>%
filter(Year %in% YoI) %>%
pivot_longer(cols = 3:37, names_to ="debiet", values_to = "Q") %>%
mutate(Q = days_in_month(as.Date(paste(Year, Month,"01", sep = "-"))) * 86400 * Q) %>%
left_join(Catchment_buitenland, by = "debiet")
select(ID, Year, Month, Q)
#————————————————————————————- # N # data as concentration
IN_buitenland_N_Monthly <- read_csv(CSV_IN_buitenland_N_mean, show_col_types = FALSE) %>%
filter(Year %in% YoI)%>%
pivot_longer(cols = 3:37, names_to = "kwaliteit", values_to = "BL_N") %>%
left_join(IN_buitenland_Q_Monthly, by = c("Year", "Month", "kwaliteit")) %>%
drop_na() %>%
mutate(BL_N = BL_N * Q * 0.001) %>%
group_by(ID, Year, Month) %>%
summarise(BL_N = sum(BL_N, na.rm = TRUE), .groups = "drop")
data as yearly N/P, divided by 12 to get monthly
IN_buitenland_N_Monthly2 <- read_csv(CSV_IN_buitenland_N_mean2, show_col_types = FALSE)
IN_buitenland_N_Monthly2 <- left_join(Catchment_Time, IN_buitenland_N_Monthly2, by = c("ID", "Year")) %>%
replace(is.na(.), 0.0)
IN_buitenland_N_Monthly <- left_join(Catchment_Time, IN_buitenland_N_Monthly, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0) %>%
mutate(BL_N = BL_N + IN_buitenland_N_Monthly2$BL_N)
write.csv(IN_buitenland_N_Monthly, file = "../Results/Inlet_SmallRivers_N_Monthly.csv", row.names = FALSE)
IN_buitenland_N_Yearly <- IN_buitenland_N_Monthly %>%
group_by(ID, Year) %>%
summarise(BL_N = sum(BL_N, na.rm = TRUE), .groups = "drop")
write.csv(IN_buitenland_N_Yearly, file = "../Results/Inlet_SmallRivers_N_Yearly.csv", row.names = FALSE)
#————————————————————————————- # P # data as concentration
IN_buitenland_P_Monthly <- read_csv(CSV_IN_buitenland_P_mean, show_col_types = FALSE) %>%
filter(Year %in% YoI)%>%
pivot_longer(cols = 3:37, names_to ="kwaliteit", values_to = "BL_P") %>%
left_join(IN_buitenland_Q_Monthly, by = c("Year", "Month", "kwaliteit")) %>%
drop_na() %>%
mutate(BL_P = BL_P * Q * 0.001) %>%
group_by(ID, Year, Month) %>%
summarise(BL_P = sum(BL_P, na.rm = TRUE), .groups = "drop")
data as yearly N/P, divided by 12 to get monthly
IN_buitenland_P_Monthly2 <- read_csv(CSV_IN_buitenland_P_mean2, show_col_types = FALSE)
IN_buitenland_P_Monthly2 <- left_join(Catchment_Time, IN_buitenland_P_Monthly2, by = c("ID", "Year")) %>%
replace(is.na(.), 0.0)
IN_buitenland_P_Monthly <- left_join(Catchment_Time, IN_buitenland_P_Monthly, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0) %>%
mutate(BL_P = BL_P + IN_buitenland_P_Monthly2$BL_P)
write.csv(IN_buitenland_P_Monthly, file = "../Results/Inlet_SmallRivers_P_Monthly.csv", row.names = FALSE)
IN_buitenland_P_Yearly <- IN_buitenland_P_Monthly %>%
group_by(ID, Year) %>%
summarise(BL_P = sum(BL_P, na.rm = TRUE), .groups = "drop")
write.csv(IN_buitenland_P_Yearly, file = "../Results/Inlet_SmallRivers_P_Yearly.csv", row.names = FALSE)
———————————————————————————————————————
prepare data for in-land routing
Retention
U&A
Soil <- as.data.frame(read_delim(TXT_Soil, show_col_types = FALSE))
Retention_UA_N <- Soil %>%
mutate(Ret_Absolute_Summer = case_when(TYPEAE == "polder" & Bodem =="Klei" ~ OW_summer_incl_ha * 10 * N_Ret_Klei_Summer_gNm2,
TYPEAE == "polder" & Bodem =="Veen" ~ OW_summer_incl_ha * 10 * N_Ret_Veen_Summer_gNm2,
TRUE ~ 1e100)) %>%
mutate(Ret_Absolute_Winter = case_when(TYPEAE == "polder" & Bodem =="Klei" ~ OW_winter_incl_ha * 10 * N_Ret_Klei_Winter_gNm2,
TYPEAE == "polder" & Bodem =="Veen" ~ OW_winter_incl_ha * 10 * N_Ret_Veen_Winter_gNm2,
TRUE ~ 1e100)) %>%
mutate(Ret_Fraction_Summer = case_when(TYPEAE == "vrij afwaterend" ~ pmin(N_a_Summer * (AfvS_m3s / OW_summer_excl_ha) ^ N_b_Summer, 0.9),
TYPEAE == "polder" & Bodem %in% c("Klei", "Veen") ~ 0.9,
TRUE ~ 0.5)) %>%
mutate(Ret_Fraction_Winter = case_when(TYPEAE == "vrij afwaterend" ~ pmin(N_a_Winter * (AfvS_m3s / OW_winter_excl_ha) ^ N_b_Winter, 0.9),
TYPEAE == "polder" & Bodem %in% c("Klei", "Veen") ~ 0.9,
TRUE ~ 0.5)) %>%
select(ID, Ret_Absolute_Summer, Ret_Absolute_Winter, Ret_Fraction_Summer, Ret_Fraction_Winter)
Retention_UA_P <- Soil %>%
mutate(Ret_Fraction_Summer = case_when(TYPEAE == "vrij afwaterend" ~ pmin(P_a_Summer * (AfvS_m3s / OW_summer_excl_ha) ^ P_b_Summer, 0.9),
TRUE ~ 0.5)) %>%
mutate(Ret_Fraction_Winter = case_when(TYPEAE == "vrij afwaterend" ~ pmin(P_a_Winter * (AfvS_m3s / OW_winter_excl_ha) ^ P_b_Winter, 0.9),
TRUE ~ 0.5)) %>%
select(ID, Ret_Fraction_Summer, Ret_Fraction_Winter)
#——————————————————————————————————- # retention fraction overige
Retention_Fra_ER_N <- Soil %>%
mutate(Ret_Fraction = case_when(TYPEAE == "polder" & Bodem %in% c("Klei", "Veen") ~ 0.0, TRUE ~ 0.2)) %>%
select(ID,Ret_Fraction)
Retention_Fra_ER_P <- Soil %>%
mutate(Ret_Fraction = 0.2) %>%
select(ID,Ret_Fraction)
#———————————————————————————————————————— # Catchment routing
Routing_538 <- as.data.frame(read_delim(TXT_Routing_STONE, show_col_types = FALSE)) %>%
rename("ID" = "FROM") #from id, to 1, weight 1, to 2, weight 2, to 3, weight 3
#———————————— # UA, retention soil specific
Routing_Stone_N <- Stone_N_Monthly %>%
left_join(Retention_UA_N, by = "ID") %>%
transmute(ID = ID, Year = Year, Month = Month, Stone_N = Stone_N,
Ret_Absolute = case_when(Month %in% 4:9 ~ Ret_Absolute_Summer, TRUE ~ Ret_Absolute_Winter),
Ret_Fraction = case_when(Month %in% 4:9 ~ Ret_Fraction_Summer, TRUE ~ Ret_Fraction_Winter))
Routing_Stone_P <- Stone_P_Monthly %>%
left_join(Retention_UA_P, by = "ID") %>%
transmute(ID = ID, Year = Year, Month = Month, Stone_P = Stone_P,
Ret_Fraction = case_when(Month %in% 4:9 ~ Ret_Fraction_Summer, TRUE ~ Ret_Fraction_Winter))
#———————————— # ER + Buitenland, retention 0.0 - 0.2
Routing_LO_N <- LO_N_Monthly %>%
left_join(Retention_Fra_ER_N, by = "ID")
Routing_IN_N <- IN_N_Monthly %>%
left_join(Retention_Fra_ER_N, by = "ID")
Routing_OR_N <- OR_N_Monthly %>%
left_join(Retention_Fra_ER_N, by = "ID")
Routing_DW_N <- DW_N_Monthly %>%
left_join(Retention_Fra_ER_N, by = "ID")
Routing_RWZI_N <- RWZI_N_Monthly %>%
left_join(Retention_Fra_ER_N, by = "ID")
Routing_BL_N <- IN_buitenland_N_Monthly %>%
left_join(Retention_Fra_ER_N, by = "ID")
Routing_LO_P <- LO_P_Monthly %>%
left_join(Retention_Fra_ER_P, by = "ID")
Routing_IN_P <- IN_P_Monthly %>%
left_join(Retention_Fra_ER_P, by = "ID")
Routing_OR_P <- OR_P_Monthly %>%
left_join(Retention_Fra_ER_P, by = "ID")
Routing_RWZI_P <- RWZI_P_Monthly %>%
left_join(Retention_Fra_ER_P, by = "ID")
Routing_BL_P <- IN_buitenland_P_Monthly %>%
left_join(Retention_Fra_ER_P, by = "ID")
Routing_ER_N <- Catchment_Time %>%
left_join(LO_N_Monthly, by = c("ID", "Year", "Month")) %>%
left_join(IN_N_Monthly, by = c("ID", "Year", "Month")) %>%
left_join(OR_N_Monthly, by = c("ID", "Year", "Month")) %>%
left_join(DW_N_Monthly, by = c("ID", "Year", "Month")) %>%
left_join(RWZI_N_Monthly, by = c("ID", "Year", "Month")) %>%
left_join(IN_buitenland_N_Monthly, by = c("ID", "Year", "Month")) %>%
transmute(ID = ID, Year = Year, Month = Month, ER_N = LO_N + IN_N + OR_N + DW_N + RWZI_N + BL_N) %>%
left_join(Retention_Fra_ER_N, by = "ID")
Routing_ER_P <- Catchment_Time %>%
left_join(LO_P_Monthly, by = c("ID", "Year", "Month")) %>%
left_join(IN_P_Monthly, by = c("ID", "Year", "Month")) %>%
left_join(OR_P_Monthly, by = c("ID", "Year", "Month")) %>%
left_join(RWZI_P_Monthly, by = c("ID", "Year", "Month")) %>%
left_join(IN_buitenland_P_Monthly, by = c("ID", "Year", "Month")) %>%
transmute(ID = ID, Year = Year, Month = Month, ER_P = LO_P + OR_P + IN_P + RWZI_P + BL_P) %>%
left_join(Retention_Fra_ER_P, by = "ID")
#———————————— #———————————— # loop begins here
Routing <- Routing_538
for (Level in 1:7) # loop from the smallest river to large ones
{
Routing_Stone_N <- mutate(Routing_Stone_N, Ret_Stone_N = Stone_N * Ret_Fraction) %>%
mutate(Ret_Stone_N = if_else(Ret_Stone_N < Ret_Absolute, Ret_Stone_N, Ret_Absolute), Afwenteling = Stone_N - Ret_Stone_N)
Routing_Stone_P <- mutate(Routing_Stone_P, Ret_Stone_P = Stone_P * Ret_Fraction, Afwenteling = Stone_P - Ret_Stone_P)
Routing_ER_N <- mutate(Routing_ER_N, Ret_ER_N = ER_N * Ret_Fraction, Afwenteling = ER_N - Ret_ER_N)
Routing_ER_P <- mutate(Routing_ER_P, Ret_ER_P = ER_P * Ret_Fraction, Afwenteling = ER_P - Ret_ER_P)
Routing_LO_N <- mutate(Routing_LO_N, Ret_LO_N = LO_N * Ret_Fraction, Afwenteling = LO_N - Ret_LO_N)
Routing_LO_P <- mutate(Routing_LO_P, Ret_LO_P = LO_P * Ret_Fraction, Afwenteling = LO_P - Ret_LO_P)
Routing_IN_N <- mutate(Routing_IN_N, Ret_IN_N = IN_N * Ret_Fraction, Afwenteling = IN_N - Ret_IN_N)
Routing_IN_P <- mutate(Routing_IN_P, Ret_IN_P = IN_P * Ret_Fraction, Afwenteling = IN_P - Ret_IN_P)
Routing_DW_N <- mutate(Routing_DW_N, Ret_DW_N = DW_N * Ret_Fraction, Afwenteling = DW_N - Ret_DW_N)
Routing_OR_N <- mutate(Routing_OR_N, Ret_OR_N = OR_N * Ret_Fraction, Afwenteling = OR_N - Ret_OR_N)
Routing_OR_P <- mutate(Routing_OR_P, Ret_OR_P = OR_P * Ret_Fraction, Afwenteling = OR_P - Ret_OR_P)
Routing_RWZI_N <- mutate(Routing_RWZI_N, Ret_RWZI_N = RWZI_N * Ret_Fraction, Afwenteling = RWZI_N - Ret_RWZI_N)
Routing_RWZI_P <- mutate(Routing_RWZI_P, Ret_RWZI_P = RWZI_P * Ret_Fraction, Afwenteling = RWZI_P - Ret_RWZI_P)
Routing_BL_N <- mutate(Routing_BL_N, Ret_BL_N = BL_N * Ret_Fraction, Afwenteling = BL_N - Ret_BL_N)
Routing_BL_P <- mutate(Routing_BL_P, Ret_BL_P = BL_P * Ret_Fraction, Afwenteling = BL_P - Ret_BL_P)
Upper <- filter(Routing, !ID %in% c(TO_1, TO_2, TO_3)) # does not receive water from other catchment
for (i in 1:nrow(Upper))
{
# Stone N
N_Stone_from <- filter(Routing_Stone_N, ID == Upper[i,1]) # from
N_Stone_to_1 <- filter(Routing_Stone_N, ID == Upper[i,2]) %>%
mutate(Stone_N = N_Stone_from$Afwenteling * Upper[i,3]) %>%
select(ID, Year, Month, Stone_N)
N_Stone_to_1 <- left_join(Catchment_Time, N_Stone_to_1, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
Routing_Stone_N <- mutate(Routing_Stone_N, Stone_N = Stone_N + N_Stone_to_1$Stone_N)
# Total ER + BL N
N_ER_from <- filter(Routing_ER_N, ID == Upper[i,1]) # from
N_ER_to_1 <- filter(Routing_ER_N, ID == Upper[i,2]) %>%
mutate(ER_N = N_ER_from$Afwenteling * Upper[i,3]) %>%
select(ID, Year, Month, ER_N)
N_ER_to_1 <- left_join(Catchment_Time, N_ER_to_1, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
Routing_ER_N <- mutate(Routing_ER_N, ER_N = ER_N + N_ER_to_1$ER_N)
# Stone P
P_Stone_from <- filter(Routing_Stone_P, ID == Upper[i,1]) # from
P_Stone_to_1 <- filter(Routing_Stone_P, ID == Upper[i,2]) %>%
mutate(Stone_P = P_Stone_from$Afwenteling * Upper[i,3]) %>%
select(ID, Year, Month, Stone_P)
P_Stone_to_1 <- left_join(Catchment_Time, P_Stone_to_1, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
Routing_Stone_P <- mutate(Routing_Stone_P, Stone_P = Stone_P + P_Stone_to_1$Stone_P)
# Total ER + BL P
P_ER_from <- filter(Routing_ER_P, ID == Upper[i,1]) # from
P_ER_to_1 <- filter(Routing_ER_P, ID == Upper[i,2]) %>%
mutate(ER_P = P_ER_from$Afwenteling * Upper[i,3]) %>%
select(ID, Year, Month, ER_P)
P_ER_to_1 <- left_join(Catchment_Time, P_ER_to_1, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
Routing_ER_P <- mutate(Routing_ER_P, ER_P = ER_P + P_ER_to_1$ER_P)
# Total LO + BL N
N_LO_from <- filter(Routing_LO_N, ID == Upper[i,1]) # from
N_LO_to_1 <- filter(Routing_LO_N, ID == Upper[i,2]) %>%
mutate(LO_N = N_LO_from$Afwenteling * Upper[i,3]) %>%
select(ID, Year, Month, LO_N)
N_LO_to_1 <- left_join(Catchment_Time, N_LO_to_1, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
Routing_LO_N <- mutate(Routing_LO_N, LO_N = LO_N + N_LO_to_1$LO_N)
# Total LO + BL P
P_LO_from <- filter(Routing_LO_P, ID == Upper[i,1]) # from
P_LO_to_1 <- filter(Routing_LO_P, ID == Upper[i,2]) %>%
mutate(LO_P = P_LO_from$Afwenteling * Upper[i,3]) %>%
select(ID, Year, Month, LO_P)
P_LO_to_1 <- left_join(Catchment_Time, P_LO_to_1, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
Routing_LO_P <- mutate(Routing_LO_P, LO_P = LO_P + P_LO_to_1$LO_P)
# Total IN + BL N
N_IN_from <- filter(Routing_IN_N, ID == Upper[i,1]) # from
N_IN_to_1 <- filter(Routing_IN_N, ID == Upper[i,2]) %>%
mutate(IN_N = N_IN_from$Afwenteling * Upper[i,3]) %>%
select(ID, Year, Month, IN_N)
N_IN_to_1 <- left_join(Catchment_Time, N_IN_to_1, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
Routing_IN_N <- mutate(Routing_IN_N, IN_N = IN_N + N_IN_to_1$IN_N)
# Total IN + BL P
P_IN_from <- filter(Routing_IN_P, ID == Upper[i,1]) # from
P_IN_to_1 <- filter(Routing_IN_P, ID == Upper[i,2]) %>%
mutate(IN_P = P_IN_from$Afwenteling * Upper[i,3]) %>%
select(ID, Year, Month, IN_P)
P_IN_to_1 <- left_join(Catchment_Time, P_IN_to_1, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
Routing_IN_P <- mutate(Routing_IN_P, IN_P = IN_P + P_IN_to_1$IN_P)
N_DW_from <- filter(Routing_DW_N, ID == Upper[i,1]) # from
N_DW_to_1 <- filter(Routing_DW_N, ID == Upper[i,2]) %>%
mutate(DW_N = N_DW_from$Afwenteling * Upper[i,3]) %>%
select(ID, Year, Month, DW_N)
N_DW_to_1 <- left_join(Catchment_Time, N_DW_to_1, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
Routing_DW_N <- mutate(Routing_DW_N, DW_N = DW_N + N_DW_to_1$DW_N)
N_OR_from <- filter(Routing_OR_N, ID == Upper[i,1]) # from
N_OR_to_1 <- filter(Routing_OR_N, ID == Upper[i,2]) %>%
mutate(OR_N = N_OR_from$Afwenteling * Upper[i,3]) %>%
select(ID, Year, Month, OR_N)
N_OR_to_1 <- left_join(Catchment_Time, N_OR_to_1, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
Routing_OR_N <- mutate(Routing_OR_N, OR_N = OR_N + N_OR_to_1$OR_N)
# Total OR + BL P
P_OR_from <- filter(Routing_OR_P, ID == Upper[i,1]) # from
P_OR_to_1 <- filter(Routing_OR_P, ID == Upper[i,2]) %>%
mutate(OR_P = P_OR_from$Afwenteling * Upper[i,3]) %>%
select(ID, Year, Month, OR_P)
P_OR_to_1 <- left_join(Catchment_Time, P_OR_to_1, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
Routing_OR_P <- mutate(Routing_OR_P, OR_P = OR_P + P_OR_to_1$OR_P)
N_RWZI_from <- filter(Routing_RWZI_N, ID == Upper[i,1]) # from
N_RWZI_to_1 <- filter(Routing_RWZI_N, ID == Upper[i,2]) %>%
mutate(RWZI_N = N_RWZI_from$Afwenteling * Upper[i,3]) %>%
select(ID, Year, Month, RWZI_N)
N_RWZI_to_1 <- left_join(Catchment_Time, N_RWZI_to_1, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
Routing_RWZI_N <- mutate(Routing_RWZI_N, RWZI_N = RWZI_N + N_RWZI_to_1$RWZI_N)
# Total RWZI + BL P
P_RWZI_from <- filter(Routing_RWZI_P, ID == Upper[i,1]) # from
P_RWZI_to_1 <- filter(Routing_RWZI_P, ID == Upper[i,2]) %>%
mutate(RWZI_P = P_RWZI_from$Afwenteling * Upper[i,3]) %>%
select(ID, Year, Month, RWZI_P)
P_RWZI_to_1 <- left_join(Catchment_Time, P_RWZI_to_1, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
Routing_RWZI_P <- mutate(Routing_RWZI_P, RWZI_P = RWZI_P + P_RWZI_to_1$RWZI_P)
N_BL_from <- filter(Routing_BL_N, ID == Upper[i,1]) # from
N_BL_to_1 <- filter(Routing_BL_N, ID == Upper[i,2]) %>%
mutate(BL_N = N_BL_from$Afwenteling * Upper[i,3]) %>%
select(ID, Year, Month, BL_N)
N_BL_to_1 <- left_join(Catchment_Time, N_BL_to_1, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
Routing_BL_N <- mutate(Routing_BL_N, BL_N = BL_N + N_BL_to_1$BL_N)
# Total BL + BL P
P_BL_from <- filter(Routing_BL_P, ID == Upper[i,1]) # from
P_BL_to_1 <- filter(Routing_BL_P, ID == Upper[i,2]) %>%
mutate(BL_P = P_BL_from$Afwenteling * Upper[i,3]) %>%
select(ID, Year, Month, BL_P)
P_BL_to_1 <- left_join(Catchment_Time, P_BL_to_1, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
Routing_BL_P <- mutate(Routing_BL_P, BL_P = BL_P + P_BL_to_1$BL_P)
if (!is.na(Upper[i,4]))
{
# Stone N
N_Stone_to_2 <- filter(Routing_Stone_N, ID == Upper[i,4]) %>%
mutate(Stone_N = N_Stone_from$Afwenteling * Upper[i,5]) %>%
select(ID, Year, Month, Stone_N)
N_Stone_to_2 <- left_join(Catchment_Time, N_Stone_to_2, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
Routing_Stone_N <- mutate(Routing_Stone_N, Stone_N = Stone_N + N_Stone_to_2$Stone_N)
# ER+BL, N
N_ER_to_2 <- filter(Routing_ER_N, ID == Upper[i,4]) %>%
mutate(ER_N = N_ER_from$Afwenteling * Upper[i,5]) %>%
select(ID, Year, Month, ER_N)
N_ER_to_2 <- left_join(Catchment_Time, N_ER_to_2, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
Routing_ER_N <- mutate(Routing_ER_N, ER_N = ER_N + N_ER_to_2$ER_N)
# Stone P
P_Stone_to_2 <- filter(Routing_Stone_P, ID == Upper[i,4]) %>%
mutate(Stone_P = P_Stone_from$Afwenteling * Upper[i,5]) %>%
select(ID, Year, Month, Stone_P)
P_Stone_to_2 <- left_join(Catchment_Time, P_Stone_to_2, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
Routing_Stone_P <- mutate(Routing_Stone_P, Stone_P = Stone_P + P_Stone_to_2$Stone_P)
# ER+BL, P
P_ER_to_2 <- filter(Routing_ER_P, ID == Upper[i,4]) %>%
mutate(ER_P = P_ER_from$Afwenteling * Upper[i,5]) %>%
select(ID, Year, Month, ER_P)
P_ER_to_2 <- left_join(Catchment_Time, P_ER_to_2, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
Routing_ER_P <- mutate(Routing_ER_P, ER_P = ER_P + P_ER_to_2$ER_P)
# LO+BL, N
N_LO_to_2 <- filter(Routing_LO_N, ID == Upper[i,4]) %>%
mutate(LO_N = N_LO_from$Afwenteling * Upper[i,5]) %>%
select(ID, Year, Month, LO_N)
N_LO_to_2 <- left_join(Catchment_Time, N_LO_to_2, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
Routing_LO_N <- mutate(Routing_LO_N, LO_N = LO_N + N_LO_to_2$LO_N)
# LO+BL, P
P_LO_to_2 <- filter(Routing_LO_P, ID == Upper[i,4]) %>%
mutate(LO_P = P_LO_from$Afwenteling * Upper[i,5]) %>%
select(ID, Year, Month, LO_P)
P_LO_to_2 <- left_join(Catchment_Time, P_LO_to_2, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
Routing_LO_P <- mutate(Routing_LO_P, LO_P = LO_P + P_LO_to_2$LO_P)
N_IN_to_2 <- filter(Routing_IN_N, ID == Upper[i,4]) %>%
mutate(IN_N = N_IN_from$Afwenteling * Upper[i,5]) %>%
select(ID, Year, Month, IN_N)
N_IN_to_2 <- left_join(Catchment_Time, N_IN_to_2, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
Routing_IN_N <- mutate(Routing_IN_N, IN_N = IN_N + N_IN_to_2$IN_N)
# IN+BL, P
P_IN_to_2 <- filter(Routing_IN_P, ID == Upper[i,4]) %>%
mutate(IN_P = P_IN_from$Afwenteling * Upper[i,5]) %>%
select(ID, Year, Month, IN_P)
P_IN_to_2 <- left_join(Catchment_Time, P_IN_to_2, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
Routing_IN_P <- mutate(Routing_IN_P, IN_P = IN_P + P_IN_to_2$IN_P)
N_DW_to_2 <- filter(Routing_DW_N, ID == Upper[i,4]) %>%
mutate(DW_N = N_DW_from$Afwenteling * Upper[i,5]) %>%
select(ID, Year, Month, DW_N)
N_DW_to_2 <- left_join(Catchment_Time, N_DW_to_2, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
Routing_DW_N <- mutate(Routing_DW_N, DW_N = DW_N + N_DW_to_2$DW_N)
N_OR_to_2 <- filter(Routing_OR_N, ID == Upper[i,4]) %>%
mutate(OR_N = N_OR_from$Afwenteling * Upper[i,5]) %>%
select(ID, Year, Month, OR_N)
N_OR_to_2 <- left_join(Catchment_Time, N_OR_to_2, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
Routing_OR_N <- mutate(Routing_OR_N, OR_N = OR_N + N_OR_to_2$OR_N)
# OR+BL, P
P_OR_to_2 <- filter(Routing_OR_P, ID == Upper[i,4]) %>%
mutate(OR_P = P_OR_from$Afwenteling * Upper[i,5]) %>%
select(ID, Year, Month, OR_P)
P_OR_to_2 <- left_join(Catchment_Time, P_OR_to_2, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
Routing_OR_P <- mutate(Routing_OR_P, OR_P = OR_P + P_OR_to_2$OR_P)
N_RWZI_to_2 <- filter(Routing_RWZI_N, ID == Upper[i,4]) %>%
mutate(RWZI_N = N_RWZI_from$Afwenteling * Upper[i,5]) %>%
select(ID, Year, Month, RWZI_N)
N_RWZI_to_2 <- left_join(Catchment_Time, N_RWZI_to_2, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
Routing_RWZI_N <- mutate(Routing_RWZI_N, RWZI_N = RWZI_N + N_RWZI_to_2$RWZI_N)
# RWZI+BL, P
P_RWZI_to_2 <- filter(Routing_RWZI_P, ID == Upper[i,4]) %>%
mutate(RWZI_P = P_RWZI_from$Afwenteling * Upper[i,5]) %>%
select(ID, Year, Month, RWZI_P)
P_RWZI_to_2 <- left_join(Catchment_Time, P_RWZI_to_2, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
Routing_RWZI_P <- mutate(Routing_RWZI_P, RWZI_P = RWZI_P + P_RWZI_to_2$RWZI_P)
N_BL_to_2 <- filter(Routing_BL_N, ID == Upper[i,4]) %>%
mutate(BL_N = N_BL_from$Afwenteling * Upper[i,5]) %>%
select(ID, Year, Month, BL_N)
N_BL_to_2 <- left_join(Catchment_Time, N_BL_to_2, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
Routing_BL_N <- mutate(Routing_BL_N, BL_N = BL_N + N_BL_to_2$BL_N)
# BL+BL, P
P_BL_to_2 <- filter(Routing_BL_P, ID == Upper[i,4]) %>%
mutate(BL_P = P_BL_from$Afwenteling * Upper[i,5]) %>%
select(ID, Year, Month, BL_P)
P_BL_to_2 <- left_join(Catchment_Time, P_BL_to_2, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
Routing_BL_P <- mutate(Routing_BL_P, BL_P = BL_P + P_BL_to_2$BL_P)
if (!is.na(Upper[i,6]))
{
# Stone N
N_Stone_to_3 <- filter(Routing_Stone_N, ID == Upper[i,6]) %>%
mutate(Stone_N = N_Stone_from$Afwenteling * Upper[i,7]) %>%
select(ID, Year, Month, Stone_N)
N_Stone_to_3 <- left_join(Catchment_Time, N_Stone_to_3, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
Routing_Stone_N <- mutate(Routing_Stone_N, Stone_N = Stone_N + N_Stone_to_3$Stone_N)
# ER+BL, N
N_ER_to_3 <- filter(Routing_ER_N, ID == Upper[i,6]) %>%
mutate(ER_N = N_ER_from$Afwenteling * Upper[i,7]) %>%
select(ID, Year, Month, ER_N)
N_ER_to_3 <- left_join(Catchment_Time, N_ER_to_3, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
Routing_ER_N <- mutate(Routing_ER_N, ER_N = ER_N + N_ER_to_3$ER_N)
# Stone P
P_Stone_to_3 <- filter(Routing_Stone_P, ID == Upper[i,6]) %>%
mutate(Stone_P = P_Stone_from$Afwenteling * Upper[i,7]) %>%
select(ID, Year, Month, Stone_P)
P_Stone_to_3 <- left_join(Catchment_Time, P_Stone_to_3, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
Routing_Stone_P <- mutate(Routing_Stone_P, Stone_P = Stone_P + P_Stone_to_3$Stone_P)
# ER+BL, P
P_ER_to_3 <- filter(Routing_ER_P, ID == Upper[i,6]) %>%
mutate(ER_P = P_ER_from$Afwenteling * Upper[i,7]) %>%
select(ID, Year, Month, ER_P)
P_ER_to_3 <- left_join(Catchment_Time, P_ER_to_3, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
Routing_ER_P <- mutate(Routing_ER_P, ER_P = ER_P + P_ER_to_3$ER_P)
# LO+BL, N
N_LO_to_3 <- filter(Routing_LO_N, ID == Upper[i,6]) %>%
mutate(LO_N = N_LO_from$Afwenteling * Upper[i,7]) %>%
select(ID, Year, Month, LO_N)
N_LO_to_3 <- left_join(Catchment_Time, N_LO_to_3, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
Routing_LO_N <- mutate(Routing_LO_N, LO_N = LO_N + N_LO_to_3$LO_N)
# LO+BL, P
P_LO_to_3 <- filter(Routing_LO_P, ID == Upper[i,6]) %>%
mutate(LO_P = P_LO_from$Afwenteling * Upper[i,7]) %>%
select(ID, Year, Month, LO_P)
P_LO_to_3 <- left_join(Catchment_Time, P_LO_to_3, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
Routing_LO_P <- mutate(Routing_LO_P, LO_P = LO_P + P_LO_to_3$LO_P)
N_IN_to_3 <- filter(Routing_IN_N, ID == Upper[i,6]) %>%
mutate(IN_N = N_IN_from$Afwenteling * Upper[i,7]) %>%
select(ID, Year, Month, IN_N)
N_IN_to_3 <- left_join(Catchment_Time, N_IN_to_3, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
Routing_IN_N <- mutate(Routing_IN_N, IN_N = IN_N + N_IN_to_3$IN_N)
# IN+BL, P
P_IN_to_3 <- filter(Routing_IN_P, ID == Upper[i,6]) %>%
mutate(IN_P = P_IN_from$Afwenteling * Upper[i,7]) %>%
select(ID, Year, Month, IN_P)
P_IN_to_3 <- left_join(Catchment_Time, P_IN_to_3, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
Routing_IN_P <- mutate(Routing_IN_P, IN_P = IN_P + P_IN_to_3$IN_P)
N_DW_to_3 <- filter(Routing_DW_N, ID == Upper[i,6]) %>%
mutate(DW_N = N_DW_from$Afwenteling * Upper[i,7]) %>%
select(ID, Year, Month, DW_N)
N_DW_to_3 <- left_join(Catchment_Time, N_DW_to_3, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
Routing_DW_N <- mutate(Routing_DW_N, DW_N = DW_N + N_DW_to_3$DW_N)
N_OR_to_3 <- filter(Routing_OR_N, ID == Upper[i,6]) %>%
mutate(OR_N = N_OR_from$Afwenteling * Upper[i,7]) %>%
select(ID, Year, Month, OR_N)
N_OR_to_3 <- left_join(Catchment_Time, N_OR_to_3, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
Routing_OR_N <- mutate(Routing_OR_N, OR_N = OR_N + N_OR_to_3$OR_N)
# OR+BL, P
P_OR_to_3 <- filter(Routing_OR_P, ID == Upper[i,6]) %>%
mutate(OR_P = P_OR_from$Afwenteling * Upper[i,7]) %>%
select(ID, Year, Month, OR_P)
P_OR_to_3 <- left_join(Catchment_Time, P_OR_to_3, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
Routing_OR_P <- mutate(Routing_OR_P, OR_P = OR_P + P_OR_to_3$OR_P)
N_RWZI_to_3 <- filter(Routing_RWZI_N, ID == Upper[i,6]) %>%
mutate(RWZI_N = N_RWZI_from$Afwenteling * Upper[i,7]) %>%
select(ID, Year, Month, RWZI_N)
N_RWZI_to_3 <- left_join(Catchment_Time, N_RWZI_to_3, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
Routing_RWZI_N <- mutate(Routing_RWZI_N, RWZI_N = RWZI_N + N_RWZI_to_3$RWZI_N)
# RWZI+BL, P
P_RWZI_to_3 <- filter(Routing_RWZI_P, ID == Upper[i,6]) %>%
mutate(RWZI_P = P_RWZI_from$Afwenteling * Upper[i,7]) %>%
select(ID, Year, Month, RWZI_P)
P_RWZI_to_3 <- left_join(Catchment_Time, P_RWZI_to_3, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
Routing_RWZI_P <- mutate(Routing_RWZI_P, RWZI_P = RWZI_P + P_RWZI_to_3$RWZI_P)
N_BL_to_3 <- filter(Routing_BL_N, ID == Upper[i,6]) %>%
mutate(BL_N = N_BL_from$Afwenteling * Upper[i,7]) %>%
select(ID, Year, Month, BL_N)
N_BL_to_3 <- left_join(Catchment_Time, N_BL_to_3, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
Routing_BL_N <- mutate(Routing_BL_N, BL_N = BL_N + N_BL_to_3$BL_N)
# BL+BL, P
P_BL_to_3 <- filter(Routing_BL_P, ID == Upper[i,6]) %>%
mutate(BL_P = P_BL_from$Afwenteling * Upper[i,7]) %>%
select(ID, Year, Month, BL_P)
P_BL_to_3 <- left_join(Catchment_Time, P_BL_to_3, by = c("ID", "Year", "Month")) %>%
replace(is.na(.), 0.0)
Routing_BL_P <- mutate(Routing_BL_P, BL_P = BL_P + P_BL_to_3$BL_P)
}
}
}
Routing <- setdiff(Routing, Upper)
}
# Catchment routing results, total retention and afwenteling from each catchment (including received from upper streams), stopped by 305 (total amount of N/P discharged into 305 is already calculated)
write.csv(Routing_Stone_N, file = "../Results/Routing_Stone_N.csv", row.names = FALSE)
write.csv(Routing_ER_N, file = "../Results/Routing_ER_N.csv", row.names = FALSE)
write.csv(Routing_Stone_P, file = "../Results/Routing_Stone_P.csv", row.names = FALSE)
write.csv(Routing_ER_P, file = "../Results/Routing_ER_P.csv", row.names = FALSE)
write.csv(Routing_LO_N, file = "../Results/Routing_LO_N.csv", row.names = FALSE)
write.csv(Routing_LO_P, file = "../Results/Routing_LO_P.csv", row.names = FALSE)
write.csv(Routing_IN_N, file = "../Results/Routing_IN_N.csv", row.names = FALSE)
write.csv(Routing_IN_P, file = "../Results/Routing_IN_P.csv", row.names = FALSE)
write.csv(Routing_DW_N, file = "../Results/Routing_DW_N.csv", row.names = FALSE)
write.csv(Routing_OR_N, file = "../Results/Routing_OR_N.csv", row.names = FALSE)
write.csv(Routing_OR_P, file = "../Results/Routing_OR_P.csv", row.names = FALSE)
write.csv(Routing_RWZI_N, file = "../Results/Routing_RWZI_N.csv", row.names = FALSE)
write.csv(Routing_RWZI_P, file = "../Results/Routing_RWZI_P.csv", row.names = FALSE)
write.csv(Routing_BL_N, file = "../Results/Routing_BL_N.csv", row.names = FALSE)
write.csv(Routing_BL_P, file = "../Results/Routing_BL_P.csv", row.names = FALSE)
routing to the north sea
direct into the north sea
Routing_Sea_Direct <- as.data.frame(read_delim(TXT_To_Sea_Direct, show_col_types = FALSE)) %>%
mutate(Distance = 0.0, Percent = 1.0) %>%
rename("Into" = "Noordzee", "Name" = "NAAM") %>%
select(ID, Name, Into, Distance, Percent)
indirect into the north sea, in meter
Routing_Sea_InDirect <- as.data.frame(read_csv(CSV_To_Sea_InDirect, show_col_types = FALSE)) %>%
pivot_longer(5:12, names_to = "Into", values_to = "Distance") %>%
mutate(Percent = case_when(NAAM == "Maas" & Into == "Haringvliet" ~ 0.29,
NAAM == "Maas" & Into == "Nieuwe Waterweg" ~ 0.68,
NAAM == "Maas" & Into == "Noordzeekanaal" ~ 0.03,
NAAM == "Schelde" & Into == "Oosterschelde" ~ 0.5,
NAAM == "Schelde" & Into == "Westerschelde" ~ 0.5,
NAAM == "Rijn West" & Into == "Haringvliet" ~ 0.29,
NAAM == "Rijn West" & Into == "Nieuwe Waterweg" ~ 0.68,
NAAM == "Rijn West" & Into == "Noordzeekanaal" ~ 0.03,
NAAM == "Rijn Oost" & Into == "IJsselmeer" ~ 1.0,
NAAM == "Rijn Noord" & Into == "Waddenzee West" ~ 1.0,
NAAM == "Eems" & Into == "Waddenzee Oost" ~ 1.0)) %>%
drop_na() %>%
rename("Name" = "NAAM") %>%
select(ID, Name, Into, Distance, Percent)
All
Routing_Sea <- bind_rows(Routing_Sea_Direct, Routing_Sea_InDirect) %>%
mutate(Release_Fra_N = exp(- K_N * Distance / (V_stream * 24 * 60 * 60)),
Release_Fra_P = exp(- K_P * Distance / (V_stream * 24 * 60 * 60)),
Ret_Extra = case_when(Into == "IJsselmeer" ~ 0.5,
Into %in% c("Haringvliet", "Westerschelde", "Oosterschelde") ~ 0.9,
TRUE ~ 1.0)) %>% # proportional to travel time, extra retention for Ijselmeer en Estuaria
mutate(Release_Fra_P = Release_Fra_P * Ret_Extra) %>%
mutate(Release_Fra_P = ifelse(Release_Fra_P < 0.1, 0.1, Release_Fra_P), Release_Fra_N = ifelse(Release_Fra_N < 0.1, 0.1, Release_Fra_N)) # afkappen zodat retentie nooit groter is dan 90%
———————————————————-
Prepare data for river routing
Stone N
Noordzee_Stone_N <- select(Routing_Stone_N, ID, Year, Month, Afwenteling) %>%
inner_join(Routing_Sea, by = "ID")
N_WenO <- filter(Noordzee_Stone_N, Into == "Wester- en Oosterschelde")
N_W <- mutate(N_WenO, Afwenteling = 0.7 * Afwenteling, Into = "Westerschelde")
N_O <- mutate(N_WenO, Afwenteling = 0.3 * Afwenteling, Into = "Oosterschelde")
Noordzee_Stone_N <- Noordzee_Stone_N %>%
filter(!Into %in% c("Wester- en Oosterschelde", "**Duitsland")) %>%
bind_rows(N_W, N_O)
Noordzee_Stone_N <- Noordzee_Stone_N %>%
mutate(Stone_N = Percent * Release_Fra_N * Afwenteling) %>%
group_by(Year, Month, Into) %>%
summarise(Stone_N = sum(Stone_N, na.rm = TRUE), .groups = "drop")
write.csv(Noordzee_Stone_N, file = "../Results/Noordzee_Stone_N.csv", row.names = FALSE)
————————————-
Stone P
Noordzee_Stone_P <- select(Routing_Stone_P, ID, Year, Month, Afwenteling) %>%
inner_join(Routing_Sea, by = "ID")
P_WenO <- filter(Noordzee_Stone_P, Into == "Wester- en Oosterschelde")
P_W <- mutate(P_WenO, Afwenteling = 0.7 * Afwenteling, Into = "Westerschelde")
P_O <- mutate(P_WenO, Afwenteling = 0.3 * Afwenteling, Into = "Oosterschelde")
Noordzee_Stone_P <- Noordzee_Stone_P %>%
filter(!Into %in% c("Wester- en Oosterschelde", "**Duitsland")) %>%
bind_rows(P_W, P_O)
Noordzee_Stone_P <- Noordzee_Stone_P %>%
mutate(Stone_P = Percent * Release_Fra_P * Afwenteling) %>%
group_by(Year, Month, Into) %>%
summarise(Stone_P = sum(Stone_P, na.rm = TRUE), .groups = "drop")
write.csv(Noordzee_Stone_P, file = "../Results/Noordzee_Stone_P.csv", row.names = FALSE)
————————————-
ER N
Noordzee_ER_N <- select(Routing_ER_N, ID, Year, Month, Afwenteling) %>%
inner_join(Routing_Sea, by = "ID")
N_WenO <- filter(Noordzee_ER_N, Into == "Wester- en Oosterschelde")
N_W <- mutate(N_WenO, Afwenteling = 0.7 * Afwenteling, Into = "Westerschelde")
N_O <- mutate(N_WenO, Afwenteling = 0.3 * Afwenteling, Into = "Oosterschelde")
Noordzee_ER_N <- Noordzee_ER_N %>%
filter(!Into %in% c("Wester- en Oosterschelde", "**Duitsland")) %>%
bind_rows(N_W, N_O)
Noordzee_ER_N <- Noordzee_ER_N %>%
mutate(ER_N = Percent * Release_Fra_N * Afwenteling) %>%
group_by(Year, Month, Into) %>%
summarise(ER_N = sum(ER_N, na.rm = TRUE), .groups = "drop")
write.csv(Noordzee_ER_N, file = "../Results/Noordzee_ER_N.csv", row.names = FALSE)
————————————-
ER P
Noordzee_ER_P <- select(Routing_ER_P, ID, Year, Month, Afwenteling) %>%
inner_join(Routing_Sea, by = "ID")
P_WenO <- filter(Noordzee_ER_P, Into == "Wester- en Oosterschelde")
P_W <- mutate(P_WenO, Afwenteling = 0.7 * Afwenteling, Into = "Westerschelde")
P_O <- mutate(P_WenO, Afwenteling = 0.3 * Afwenteling, Into = "Oosterschelde")
Noordzee_ER_P <- Noordzee_ER_P %>%
filter(!Into %in% c("Wester- en Oosterschelde", "**Duitsland")) %>%
bind_rows(P_W, P_O)
Noordzee_ER_P <- Noordzee_ER_P %>%
mutate(ER_P = Percent * Release_Fra_P * Afwenteling) %>%
group_by(Year, Month, Into) %>%
summarise(ER_P = sum(ER_P, na.rm = TRUE), .groups = "drop")
write.csv(Noordzee_ER_P, file = "../Results/Noordzee_ER_P.csv", row.names = FALSE)
————————————-
IN N
Noordzee_IN_N <- select(Routing_IN_N, ID, Year, Month, Afwenteling) %>%
inner_join(Routing_Sea, by = "ID")
N_WenO <- filter(Noordzee_IN_N, Into == "Wester- en Oosterschelde")
N_W <- mutate(N_WenO, Afwenteling = 0.7 * Afwenteling, Into = "Westerschelde")
N_O <- mutate(N_WenO, Afwenteling = 0.3 * Afwenteling, Into = "Oosterschelde")
Noordzee_IN_N <- Noordzee_IN_N %>%
filter(!Into %in% c("Wester- en Oosterschelde", "**Duitsland")) %>%
bind_rows(N_W, N_O)
Noordzee_IN_N <- Noordzee_IN_N %>%
mutate(IN_N = Percent * Release_Fra_N * Afwenteling) %>%
group_by(Year, Month, Into) %>%
summarise(IN_N = sum(IN_N, na.rm = TRUE), .groups = "drop")
write.csv(Noordzee_IN_N, file = "../Results/Noordzee_IN_N.csv", row.names = FALSE)
————————————-
IN P
Noordzee_IN_P <- select(Routing_IN_P, ID, Year, Month, Afwenteling) %>%
inner_join(Routing_Sea, by = "ID")
P_WenO <- filter(Noordzee_IN_P, Into == "Wester- en Oosterschelde")
P_W <- mutate(P_WenO, Afwenteling = 0.7 * Afwenteling, Into = "Westerschelde")
P_O <- mutate(P_WenO, Afwenteling = 0.3 * Afwenteling, Into = "Oosterschelde")
Noordzee_IN_P <- Noordzee_IN_P %>%
filter(!Into %in% c("Wester- en Oosterschelde", "**Duitsland")) %>%
bind_rows(P_W, P_O)
Noordzee_IN_P <- Noordzee_IN_P %>%
mutate(IN_P = Percent * Release_Fra_P * Afwenteling) %>%
group_by(Year, Month, Into) %>%
summarise(IN_P = sum(IN_P, na.rm = TRUE), .groups = "drop")
write.csv(Noordzee_IN_P, file = "../Results/Noordzee_IN_P.csv", row.names = FALSE)
————————————-
LO N
Noordzee_LO_N <- select(Routing_LO_N, ID, Year, Month, Afwenteling) %>%
inner_join(Routing_Sea, by = "ID")
N_WenO <- filter(Noordzee_LO_N, Into == "Wester- en Oosterschelde")
N_W <- mutate(N_WenO, Afwenteling = 0.7 * Afwenteling, Into = "Westerschelde")
N_O <- mutate(N_WenO, Afwenteling = 0.3 * Afwenteling, Into = "Oosterschelde")
Noordzee_LO_N <- Noordzee_LO_N %>%
filter(!Into %in% c("Wester- en Oosterschelde", "**Duitsland")) %>%
bind_rows(N_W, N_O)
Noordzee_LO_N <- Noordzee_LO_N %>%
mutate(LO_N = Percent * Release_Fra_N * Afwenteling) %>%
group_by(Year, Month, Into) %>%
summarise(LO_N = sum(LO_N, na.rm = TRUE), .groups = "drop")
write.csv(Noordzee_LO_N, file = "../Results/Noordzee_LO_N.csv", row.names = FALSE)
————————————-
LO P
Noordzee_LO_P <- select(Routing_LO_P, ID, Year, Month, Afwenteling) %>%
inner_join(Routing_Sea, by = "ID")
P_WenO <- filter(Noordzee_LO_P, Into == "Wester- en Oosterschelde")
P_W <- mutate(P_WenO, Afwenteling = 0.7 * Afwenteling, Into = "Westerschelde")
P_O <- mutate(P_WenO, Afwenteling = 0.3 * Afwenteling, Into = "Oosterschelde")
Noordzee_LO_P <- Noordzee_LO_P %>%
filter(!Into %in% c("Wester- en Oosterschelde", "**Duitsland")) %>%
bind_rows(P_W, P_O)
Noordzee_LO_P <- Noordzee_LO_P %>%
mutate(LO_P = Percent * Release_Fra_P * Afwenteling) %>%
group_by(Year, Month, Into) %>%
summarise(LO_P = sum(LO_P, na.rm = TRUE), .groups = "drop")
write.csv(Noordzee_LO_P, file = "../Results/Noordzee_LO_P.csv", row.names = FALSE)
————————————-
OR N
Noordzee_OR_N <- select(Routing_OR_N, ID, Year, Month, Afwenteling) %>%
inner_join(Routing_Sea, by = "ID")
N_WenO <- filter(Noordzee_OR_N, Into == "Wester- en Oosterschelde")
N_W <- mutate(N_WenO, Afwenteling = 0.7 * Afwenteling, Into = "Westerschelde")
N_O <- mutate(N_WenO, Afwenteling = 0.3 * Afwenteling, Into = "Oosterschelde")
Noordzee_OR_N <- Noordzee_OR_N %>%
filter(!Into %in% c("Wester- en Oosterschelde", "**Duitsland")) %>%
bind_rows(N_W, N_O)
Noordzee_OR_N <- Noordzee_OR_N %>%
mutate(OR_N = Percent * Release_Fra_N * Afwenteling) %>%
group_by(Year, Month, Into) %>%
summarise(OR_N = sum(OR_N, na.rm = TRUE), .groups = "drop")
write.csv(Noordzee_OR_N, file = "../Results/Noordzee_OR_N.csv", row.names = FALSE)
————————————-
OR P
Noordzee_OR_P <- select(Routing_OR_P, ID, Year, Month, Afwenteling) %>%
inner_join(Routing_Sea, by = "ID")
P_WenO <- filter(Noordzee_OR_P, Into == "Wester- en Oosterschelde")
P_W <- mutate(P_WenO, Afwenteling = 0.7 * Afwenteling, Into = "Westerschelde")
P_O <- mutate(P_WenO, Afwenteling = 0.3 * Afwenteling, Into = "Oosterschelde")
Noordzee_OR_P <- Noordzee_OR_P %>%
filter(!Into %in% c("Wester- en Oosterschelde", "**Duitsland")) %>%
bind_rows(P_W, P_O)
Noordzee_OR_P <- Noordzee_OR_P %>%
mutate(OR_P = Percent * Release_Fra_P * Afwenteling) %>%
group_by(Year, Month, Into) %>%
summarise(OR_P = sum(OR_P, na.rm = TRUE), .groups = "drop")
write.csv(Noordzee_OR_P, file = "../Results/Noordzee_OR_P.csv", row.names = FALSE)
————————————-
DW N
Noordzee_DW_N <- select(Routing_DW_N, ID, Year, Month, Afwenteling) %>%
inner_join(Routing_Sea, by = "ID")
N_WenO <- filter(Noordzee_DW_N, Into == "Wester- en Oosterschelde")
N_W <- mutate(N_WenO, Afwenteling = 0.7 * Afwenteling, Into = "Westerschelde")
N_O <- mutate(N_WenO, Afwenteling = 0.3 * Afwenteling, Into = "Oosterschelde")
Noordzee_DW_N <- Noordzee_DW_N %>%
filter(!Into %in% c("Wester- en Oosterschelde", "**Duitsland")) %>%
bind_rows(N_W, N_O)
Noordzee_DW_N <- Noordzee_DW_N %>%
mutate(DW_N = Percent * Release_Fra_N * Afwenteling) %>%
group_by(Year, Month, Into) %>%
summarise(DW_N = sum(DW_N, na.rm = TRUE), .groups = "drop")
write.csv(Noordzee_DW_N, file = "../Results/Noordzee_DW_N.csv", row.names = FALSE)
————————————-
RWZI N
Noordzee_RWZI_N <- select(Routing_RWZI_N, ID, Year, Month, Afwenteling) %>%
inner_join(Routing_Sea, by = "ID")
N_WenO <- filter(Noordzee_RWZI_N, Into == "Wester- en Oosterschelde")
N_W <- mutate(N_WenO, Afwenteling = 0.7 * Afwenteling, Into = "Westerschelde")
N_O <- mutate(N_WenO, Afwenteling = 0.3 * Afwenteling, Into = "Oosterschelde")
Noordzee_RWZI_N <- Noordzee_RWZI_N %>%
filter(!Into %in% c("Wester- en Oosterschelde", "**Duitsland")) %>%
bind_rows(N_W, N_O)
Noordzee_RWZI_N <- Noordzee_RWZI_N %>%
mutate(RWZI_N = Percent * Release_Fra_N * Afwenteling) %>%
group_by(Year, Month, Into) %>%
summarise(RWZI_N = sum(RWZI_N, na.rm = TRUE), .groups = "drop")
write.csv(Noordzee_RWZI_N, file = "../Results/Noordzee_RWZI_N.csv", row.names = FALSE)
————————————-
RWZI P
Noordzee_RWZI_P <- select(Routing_RWZI_P, ID, Year, Month, Afwenteling) %>%
inner_join(Routing_Sea, by = "ID")
P_WenO <- filter(Noordzee_RWZI_P, Into == "Wester- en Oosterschelde")
P_W <- mutate(P_WenO, Afwenteling = 0.7 * Afwenteling, Into = "Westerschelde")
P_O <- mutate(P_WenO, Afwenteling = 0.3 * Afwenteling, Into = "Oosterschelde")
Noordzee_RWZI_P <- Noordzee_RWZI_P %>%
filter(!Into %in% c("Wester- en Oosterschelde", "**Duitsland")) %>%
bind_rows(P_W, P_O)
Noordzee_RWZI_P <- Noordzee_RWZI_P %>%
mutate(RWZI_P = Percent * Release_Fra_P * Afwenteling) %>%
group_by(Year, Month, Into) %>%
summarise(RWZI_P = sum(RWZI_P, na.rm = TRUE), .groups = "drop")
write.csv(Noordzee_RWZI_P, file = "../Results/Noordzee_RWZI_P.csv", row.names = FALSE)
————————————-
BL N
Noordzee_BL_N <- select(Routing_BL_N, ID, Year, Month, Afwenteling) %>%
inner_join(Routing_Sea, by = "ID")
N_WenO <- filter(Noordzee_BL_N, Into == "Wester- en Oosterschelde")
N_W <- mutate(N_WenO, Afwenteling = 0.7 * Afwenteling, Into = "Westerschelde")
N_O <- mutate(N_WenO, Afwenteling = 0.3 * Afwenteling, Into = "Oosterschelde")
Noordzee_BL_N <- Noordzee_BL_N %>%
filter(!Into %in% c("Wester- en Oosterschelde", "**Duitsland")) %>%
bind_rows(N_W, N_O)
Noordzee_BL_N <- Noordzee_BL_N %>%
mutate(BL_N = Percent * Release_Fra_N * Afwenteling) %>%
group_by(Year, Month, Into) %>%
summarise(BL_N = sum(BL_N, na.rm = TRUE), .groups = "drop")
write.csv(Noordzee_BL_N, file = "../Results/Noordzee_BL_N.csv", row.names = FALSE)
————————————-
BL P
Noordzee_BL_P <- select(Routing_BL_P, ID, Year, Month, Afwenteling) %>%
inner_join(Routing_Sea, by = "ID")
P_WenO <- filter(Noordzee_BL_P, Into == "Wester- en Oosterschelde")
P_W <- mutate(P_WenO, Afwenteling = 0.7 * Afwenteling, Into = "Westerschelde")
P_O <- mutate(P_WenO, Afwenteling = 0.3 * Afwenteling, Into = "Oosterschelde")
Noordzee_BL_P <- Noordzee_BL_P %>%
filter(!Into %in% c("Wester- en Oosterschelde", "**Duitsland")) %>%
bind_rows(P_W, P_O)
Noordzee_BL_P <- Noordzee_BL_P %>%
mutate(BL_P = Percent * Release_Fra_P * Afwenteling) %>%
group_by(Year, Month, Into) %>%
summarise(BL_P = sum(BL_P, na.rm = TRUE), .groups = "drop")
write.csv(Noordzee_BL_P, file = "../Results/Noordzee_BL_P.csv", row.names = FALSE)
————————————-
Inlet big rivers
Noordzee_Inlet_N <- select(Inlet_N_Monthly, ID, Year, Month, Afwenteling = Inlet_N) %>%
inner_join(Routing_Sea, by = "ID") %>%
mutate(Inlet_N = Percent * Release_Fra_N * Afwenteling) %>%
group_by(Year, Month, Into) %>%
summarise(Inlet_N = sum(Inlet_N, na.rm = TRUE), .groups = "drop")
write.csv(Noordzee_Inlet_N, file = "../Results/Noordzee_BL_BigRivers_N.csv", row.names = FALSE)
————————————-
Inlet P, big rivers
Noordzee_Inlet_P <- select(Inlet_P_Monthly, ID, Year, Month, Afwenteling = Inlet_P) %>%
inner_join(Routing_Sea, by = "ID") %>%
mutate(Inlet_P = Percent * Release_Fra_P * Afwenteling) %>%
group_by(Year, Month, Into) %>%
summarise(Inlet_P = sum(Inlet_P, na.rm = TRUE), .groups = "drop")
write.csv(Noordzee_Inlet_P, file = "../Results/Noordzee_BL_BigRivers_P.csv", row.names = FALSE)
————————————-
#——————————————–
LS0tDQp0aXRsZTogIkVDSE8gdHV0b3JpYWwiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQpFQ0hPIGlzIGEgc3lzdGVtIG9mIFIgc2NyaXB0cyBhbmQgZnVuY3Rpb25zIGZvciBxdWFudGlmeWluZyB0aGUgbnV0cmllbnRzIHNvdXJjZXMgYW5kIHRoZWlyIHRyYW5zcG9ydCBpbiBjYXRjaG1lbnRzIG9mIGRpZmZlcmVudCBzY2FsZXMuDQpNYWluIHNvdXJjZXMgYXJlOg0KDQotIEFOSU1PIG1vZGVsLCBPdXRmbG93IG9mIGFncmljdWx0dXJlIGFuZCBuYXR1cmUgYXJlYQ0KLSBFbWlzc2lvbiBSZWdpc3RyYXRpb24gKEluZHVzdHJ5LCBBdG1vc3BoZXJpYyBkZXBvc2l0aW9uLCBPdGhlciBhZ3JpY3VsdHVyZSwgV2F0ZXIgdHJlYXRtZW50IHBsYW50cywgT3RoZXJzKSBbRVJdKGh0dHA6Ly93d3cuZW1pc3NpZXJlZ2lzdHJhdGllLm5sL2VycHVibGllay9lcnB1Yi9kZWZhdWx0Lm5sLmFzcHgpDQotIEZvcmVpZ24gcml2ZXJzL3N0cmVhbXMgW1JXU10oaHR0cHM6Ly93YXRlcmluZm8ucndzLm5sLyMhL25hdi9leHBlcnQvKQ0KDQoxLiBMb2FkIHBhY2thZ2VzLCBjb25zdGFudHMgYW5kIGZ1bmN0aW9ucw0KDQpgYGB7cn0NCnBhY21hbjo6cF9sb2FkKCJ0aWR5dmVyc2UiLCAic2YiLCAiUk9EQkMiLCAibHVicmlkYXRlIikNCmBgYA0KMi4gU2V0dGluZ3MgYW5kIGZ1bmN0aW9ucw0KYGBge3J9DQpzb3VyY2UoIkRpcmVjdG9yaWVzLlIiKQ0Kc291cmNlKCJGdW5jdGlvbnMuUiIpDQpzb3VyY2UoIkNvbnN0YW50cy5SIikNCmBgYA0KMy4gbG9hZCBTVE9ORSBzaGFwZSBmaWxlczogNTM4IGNhdGNobWVudHMgKGhhKSwgYW5kIG1lcmdlIHdpdGggc3RvbmUgcGxvdCBudW1iZXJzDQpgYGB7cn0NCkNhdGNobWVudCA8LSByZWFkX2NzdihDU1ZfQ2F0Y2htZW50LCBzaG93X2NvbF90eXBlcyA9IEZBTFNFKSAlPiUNCiAgcmVuYW1lKElEID0gMSwgV2F0ZXJfQm9keSA9IDIsIEFyZWFfQ2F0Y2htZW50ID0gMykNCkNhdGNobWVudA0KYGBgDQo0LiBQcmVwYXJlIGZ1bmRhbWVudGFsIGRhdGEgZnJhbWUNCmBgYHtyfQ0KQ2F0Y2htZW50X1RpbWUgPC0gdGliYmxlKElEID0gcmVwKDE6Tm9DLCBlYWNoID0gbGVuZ3RoKFlvSSkgKiAxMiksIFllYXIgPSByZXAocmVwKFlvSSwgZWFjaCA9IDEyKSwgTm9DKSwgTW9udGggPSByZXAoMToxMiwgTm9DICogbGVuZ3RoKFlvSSkpKQ0KQ2F0Y2htZW50X1RpbWUNCmBgYA0KNS4gQ2F0Y2htZW50IElEIHZzIFN0b25lIHBsb3QgbnVtYmVyLCB3aXRoIHBsb3QgYXJlYQ0KYGBge3J9DQpDYXRjaG1lbnRfUGxvdCA8LSBhcy5kYXRhLmZyYW1lKHJlYWRfZGVsaW0oVFhUX0NhdGNobWVudF9QbG90LCBzaG93X2NvbF90eXBlcyA9IEZBTFNFKSkgJT4lDQogIHJlbmFtZShJRCA9IDEsIFBsb3QgPSAyLCBBcmVhX1Bsb3QgPSAzKQ0KQ2F0Y2htZW50X1Bsb3QNCmBgYA0KNi4gbG9hZCBTVE9ORSBvdXRwdXQgZGF0YSwgeWVhcnMgb2YgaW50ZXJlc3QsIFAoa2cvbTIvZGVjYWRlKSwgTihrZy9tMi9kZWNhZGUpDQpgYGB7cn0NClN0b25lIDwtIHJlYWRfY3N2KENTVl9TdG9uZSwgc2hvd19jb2xfdHlwZXMgPSBGQUxTRSkNClN0b25lDQpgYGANCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgTiAoa2cpDQojIE1vbnRobHkNCmBgYHtyfQ0KU3RvbmVfTl9Nb250aGx5IDwtIFN0b25lICU+JQ0KICBzZWxlY3QoUGxvdCwgWWVhciwgTW9udGgsIE4pICU+JQ0KICBncm91cF9ieShQbG90LCBZZWFyLCBNb250aCkgJT4lDQogIHN1bW1hcmlzZShOID0gc3VtKE4sIG5hLnJtID0gVFJVRSksIC5ncm91cHMgPSAiZHJvcCIpICU+JQ0KICByaWdodF9qb2luKENhdGNobWVudF9QbG90LCBieSA9ICJQbG90IikgJT4lDQogIG11dGF0ZShOID0gQXJlYV9QbG90ICogTikgJT4lDQogIGdyb3VwX2J5KElELCBZZWFyLCBNb250aCkgJT4lDQogIHN1bW1hcmlzZShTdG9uZV9OID0gc3VtKE4sIG5hLnJtID0gVFJVRSksIC5ncm91cHMgPSAiZHJvcCIpDQpTdG9uZV9OX01vbnRobHkgPC0gbGVmdF9qb2luKENhdGNobWVudF9UaW1lLCBTdG9uZV9OX01vbnRobHksIGJ5ID0gYygiSUQiLCAiWWVhciIsICJNb250aCIpKSAlPiUNCiAgcmVwbGFjZShpcy5uYSguKSwgMC4wKQ0Kd3JpdGUuY3N2KFN0b25lX05fTW9udGhseSwgZmlsZSA9ICIuLi9SZXN1bHRzL1N0b25lX05fTW9udGhseS5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkNCmBgYA0KDQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyBZZWFybHkNCmBgYHtyfQ0KU3RvbmVfTl9ZZWFybHkgPC0gU3RvbmVfTl9Nb250aGx5ICU+JQ0KICBncm91cF9ieShJRCwgWWVhcikgJT4lDQogIHN1bW1hcmlzZShTdG9uZV9OID0gc3VtKFN0b25lX04sIG5hLnJtID0gVFJVRSksIC5ncm91cHMgPSAiZHJvcCIpDQp3cml0ZS5jc3YoU3RvbmVfTl9ZZWFybHksIGZpbGUgPSAiLi4vUmVzdWx0cy9TdG9uZV9OX1llYXJseS5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkNCmBgYA0KIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIFAgKGtnKQ0KIyBNb250aGx5DQpgYGB7cn0NClN0b25lX1BfTW9udGhseSA8LSBTdG9uZSAlPiUNCiAgc2VsZWN0KFBsb3QsIFllYXIsIE1vbnRoLCBQKSAlPiUNCiAgZ3JvdXBfYnkoUGxvdCwgWWVhciwgTW9udGgpICU+JQ0KICBzdW1tYXJpc2UoUCA9IHN1bShQLCBuYS5ybSA9IFRSVUUpLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUNCiAgcmlnaHRfam9pbihDYXRjaG1lbnRfUGxvdCwgYnkgPSAiUGxvdCIpICU+JQ0KICBtdXRhdGUoUCA9IEFyZWFfUGxvdCAqIFApICU+JQ0KICBncm91cF9ieShJRCwgWWVhciwgTW9udGgpICU+JQ0KICBzdW1tYXJpc2UoU3RvbmVfUCA9IHN1bShQLCBuYS5ybSA9IFRSVUUpLCAuZ3JvdXBzID0gImRyb3AiKQ0KU3RvbmVfUF9Nb250aGx5IDwtIGxlZnRfam9pbihDYXRjaG1lbnRfVGltZSwgU3RvbmVfUF9Nb250aGx5LCBieSA9IGMoIklEIiwgIlllYXIiLCAiTW9udGgiKSkgJT4lDQogIHJlcGxhY2UoaXMubmEoLiksIDAuMCkNCndyaXRlLmNzdihTdG9uZV9QX01vbnRobHksIGZpbGUgPSAiLi4vUmVzdWx0cy9TdG9uZV9QX01vbnRobHkuY3N2Iiwgcm93Lm5hbWVzID0gRkFMU0UpDQpgYGANCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIFllYXJseQ0KYGBge3J9DQpTdG9uZV9QX1llYXJseSA8LSBTdG9uZV9QX01vbnRobHkgJT4lDQogIGdyb3VwX2J5KElELCBZZWFyKSAlPiUNCiAgc3VtbWFyaXNlKFN0b25lX1AgPSBzdW0oU3RvbmVfUCwgbmEucm0gPSBUUlVFKSwgLmdyb3VwcyA9ICJkcm9wIikNCndyaXRlLmNzdihTdG9uZV9QX1llYXJseSwgZmlsZSA9ICIuLi9SZXN1bHRzL1N0b25lX1BfWWVhcmx5LmNzdiIsIHJvdy5uYW1lcyA9IEZBTFNFKQ0KYGBgDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQojIEVtaXNzaW9uIGZyb20gRW1pc3Npb24gUmVnaXN0cmF0aW9uIChFUikgZm9yIG9wZW4gd2F0ZXIsIGtnDQojIE4gdG90YWwgKDMwMyksIFAgdG90YWwgKDMwMiksIFEoODUpDQoNCiMgbG9hZCBDYXRjaG1lbnQtRVIgbWF0Y2hpbmcgZmlsZSAoNTM4IGNhdGNobWVudHMgb3ZlcmxheSB3aXRoIGdhZjkwKQ0KYGBge3J9DQpDYXRjaG1lbnRfRVIgPC0gcmVhZF9jc3YoQ1NWX0VSLCBzaG93X2NvbF90eXBlcyA9IEZBTFNFKQ0KYGBgDQoNCiMgRW1pc3Npb25zLCB3aXRoIEFJIGNvZGUNCmBgYHtyfQ0KRVJfTiA8LSByZWFkX2NzdihDU1ZfRVJfTiwgc2hvd19jb2xfdHlwZXMgPSBGQUxTRSkNCkVSX1AgPC0gcmVhZF9jc3YoQ1NWX0VSX1AsIHNob3dfY29sX3R5cGVzID0gRkFMU0UpDQpgYGANCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyBSV1pJDQpgYGB7cn0NClJXWklfQ2F0Y2htZW50X0FJIDwtIHJlYWRfY3N2KENTVl9SV1pJX0NhdGNobWVudCwgc2hvd19jb2xfdHlwZXMgPSBGQUxTRSkNCmBgYA0KIyBODQpgYGB7cn0NClJXWklfTl9ZZWFybHkgPC0gZmlsdGVyKEVSX04sIEdyb3VwID09ICJSV1pJIiwgIWlzLm5hKEVtaXNzaW9uKSkgJT4lDQogIGxlZnRfam9pbihSV1pJX0NhdGNobWVudF9BSSwgYnkgPSAiQUlfY29kZSIpICU+JQ0KICBncm91cF9ieShJRCwgWWVhcikgJT4lDQogIHN1bW1hcmlzZShSV1pJX04gPSBzdW0oRW1pc3Npb24sIG5hLnJtID0gVFJVRSksIC5ncm91cHMgPSAiZHJvcCIpICU+JQ0KICBzcHJlYWQoWWVhciwgUldaSV9OKSAlPiUNCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSAyOjExLCBuYW1lc190byA9IlllYXIiLCB2YWx1ZXNfdG8gPSAiUldaSV9OIikgJT4lDQogIGdyb3VwX2J5KElEKSAlPiUNCiAgbXV0YXRlKFJXWklfTiA9IGlmZWxzZShpcy5uYShSV1pJX04pLCBtZWFuKFJXWklfTiwgbmEucm0gPSBUUlVFKSwgUldaSV9OKSkNCndyaXRlLmNzdihSV1pJX05fWWVhcmx5LCBmaWxlID0gIi4uL1Jlc3VsdHMvUldaSV9OX1llYXJseS5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkNCmBgYA0KYGBge3J9DQpSV1pJX05fWWVhcmx5JFllYXIgPC0gYXMubnVtZXJpYyhSV1pJX05fWWVhcmx5JFllYXIpDQpSV1pJX05fTW9udGhseSA8LSBtdXRhdGUoUldaSV9OX1llYXJseSwgUldaSV9OID0gUldaSV9OLzEyKQ0KUldaSV9OX01vbnRobHkgPC0gbGVmdF9qb2luKENhdGNobWVudF9UaW1lLCBSV1pJX05fTW9udGhseSwgYnkgPSBjKCJJRCIsICJZZWFyIikpICU+JQ0KICByZXBsYWNlKGlzLm5hKC4pLCAwLjApDQp3cml0ZS5jc3YoUldaSV9OX01vbnRobHksIGZpbGUgPSAiLi4vUmVzdWx0cy9SV1pJX05fTW9udGhseS5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkNCmBgYA0KDQojIFANCmBgYHtyfQ0KUldaSV9QX1llYXJseSA8LSBmaWx0ZXIoRVJfUCwgR3JvdXAgPT0gIlJXWkkiLCAhaXMubmEoRW1pc3Npb24pKSAlPiUNCiAgbGVmdF9qb2luKFJXWklfQ2F0Y2htZW50X0FJLCBieSA9ICJBSV9jb2RlIikgJT4lDQogIGdyb3VwX2J5KElELCBZZWFyKSAlPiUNCiAgc3VtbWFyaXNlKFJXWklfUCA9IHN1bShFbWlzc2lvbiwgbmEucm0gPSBUUlVFKSwgLmdyb3VwcyA9ICJkcm9wIikgJT4lDQogIHNwcmVhZChZZWFyLCBSV1pJX1ApICU+JQ0KICBwaXZvdF9sb25nZXIoY29scyA9IDI6MTEsIG5hbWVzX3RvID0iWWVhciIsIHZhbHVlc190byA9ICJSV1pJX1AiKSAlPiUNCiAgZ3JvdXBfYnkoSUQpICU+JQ0KICBtdXRhdGUoUldaSV9QID0gaWZlbHNlKGlzLm5hKFJXWklfUCksIG1lYW4oUldaSV9QLCBuYS5ybSA9IFRSVUUpLCBSV1pJX1ApKQ0Kd3JpdGUuY3N2KFJXWklfUF9ZZWFybHksIGZpbGUgPSAiLi4vUmVzdWx0cy9SV1pJX1BfWWVhcmx5LmNzdiIsIHJvdy5uYW1lcyA9IEZBTFNFKQ0KYGBgDQpgYGB7cn0NClJXWklfUF9ZZWFybHkkWWVhciA8LSBhcy5udW1lcmljKFJXWklfUF9ZZWFybHkkWWVhcikNClJXWklfUF9Nb250aGx5IDwtIG11dGF0ZShSV1pJX1BfWWVhcmx5LCBSV1pJX1AgPSBSV1pJX1AvMTIpDQpSV1pJX1BfTW9udGhseSA8LSBsZWZ0X2pvaW4oQ2F0Y2htZW50X1RpbWUsIFJXWklfUF9Nb250aGx5LCBieSA9IGMoIklEIiwgIlllYXIiKSkgJT4lDQogIHJlcGxhY2UoaXMubmEoLiksIDAuMCkNCndyaXRlLmNzdihSV1pJX1BfTW9udGhseSwgZmlsZSA9ICIuLi9SZXN1bHRzL1JXWklfUF9Nb250aGx5LmNzdiIsIHJvdy5uYW1lcyA9IEZBTFNFKQ0KYGBgDQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgIyBPdmVyaWdlIGxhbmRib3V3ZWVtaXNzaWVzDQojIE4NCmBgYHtyfQ0KTE9fTl9ZZWFybHkgPC0gZmlsdGVyKEVSX04sIEdyb3VwID09ICJMTyIsICFpcy5uYShFbWlzc2lvbikpICU+JQ0KICBsZWZ0X2pvaW4oQ2F0Y2htZW50X0VSLCAgYnkgPSAiQUlfY29kZSIpICU+JQ0KICBncm91cF9ieShJRCwgWWVhcikgJT4lDQogIHN1bW1hcmlzZShMT19OID0gc3VtKEVtaXNzaW9uLCBuYS5ybSA9IFRSVUUpLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUNCiAgc3ByZWFkKFllYXIsIExPX04pICU+JQ0KICBwaXZvdF9sb25nZXIoY29scyA9IDI6MTEsIG5hbWVzX3RvID0iWWVhciIsIHZhbHVlc190byA9ICJMT19OIikgJT4lDQogIGdyb3VwX2J5KElEKSAlPiUNCiAgbXV0YXRlKExPX04gPSBpZmVsc2UoaXMubmEoTE9fTiksIG1lYW4oTE9fTiwgbmEucm0gPSBUUlVFKSwgTE9fTikpDQp3cml0ZS5jc3YoTE9fTl9ZZWFybHksIGZpbGUgPSAiLi4vUmVzdWx0cy9MT19OX1llYXJseS5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkNCmBgYA0KYGBge3J9DQpMT19OX1llYXJseSRZZWFyIDwtIGFzLm51bWVyaWMoTE9fTl9ZZWFybHkkWWVhcikNCkxPX05fTW9udGhseSA8LSBtdXRhdGUoTE9fTl9ZZWFybHksIExPX04gPSBMT19OLzEyKQ0KTE9fTl9Nb250aGx5IDwtIGxlZnRfam9pbihDYXRjaG1lbnRfVGltZSwgTE9fTl9Nb250aGx5LCBieSA9IGMoIklEIiwgIlllYXIiKSkgJT4lDQogIHJlcGxhY2UoaXMubmEoLiksIDAuMCkNCndyaXRlLmNzdihMT19OX01vbnRobHksIGZpbGUgPSAiLi4vUmVzdWx0cy9MT19OX01vbnRobHkuY3N2Iiwgcm93Lm5hbWVzID0gRkFMU0UpDQpgYGANCiMgSW5kdXN0cnkNCmBgYHtyfQ0KSU5fTl9ZZWFybHkgPC0gZmlsdGVyKEVSX04sIEdyb3VwID09ICJJTiIsICFpcy5uYShFbWlzc2lvbikpICU+JQ0KICBsZWZ0X2pvaW4oQ2F0Y2htZW50X0VSLCAgYnkgPSAiQUlfY29kZSIpICU+JQ0KICBncm91cF9ieShJRCwgWWVhcikgJT4lDQogIHN1bW1hcmlzZShJTl9OID0gc3VtKEVtaXNzaW9uLCBuYS5ybSA9IFRSVUUpLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUNCiAgc3ByZWFkKFllYXIsIElOX04pICU+JQ0KICBwaXZvdF9sb25nZXIoY29scyA9IDI6MTEsIG5hbWVzX3RvID0iWWVhciIsIHZhbHVlc190byA9ICJJTl9OIikgJT4lDQogIGdyb3VwX2J5KElEKSAlPiUNCiAgbXV0YXRlKElOX04gPSBpZmVsc2UoaXMubmEoSU5fTiksIG1lYW4oSU5fTiwgbmEucm0gPSBUUlVFKSwgSU5fTikpDQp3cml0ZS5jc3YoSU5fTl9ZZWFybHksIGZpbGUgPSAiLi4vUmVzdWx0cy9JTl9OX1llYXJseS5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkNCmBgYA0KYGBge3J9DQpJTl9OX1llYXJseSRZZWFyIDwtIGFzLm51bWVyaWMoSU5fTl9ZZWFybHkkWWVhcikNCklOX05fTW9udGhseSA8LSBtdXRhdGUoSU5fTl9ZZWFybHksIElOX04gPSBJTl9OLzEyKQ0KSU5fTl9Nb250aGx5IDwtIGxlZnRfam9pbihDYXRjaG1lbnRfVGltZSwgSU5fTl9Nb250aGx5LCBieSA9IGMoIklEIiwgIlllYXIiKSkgJT4lDQogIHJlcGxhY2UoaXMubmEoLiksIDAuMCkNCndyaXRlLmNzdihJTl9OX01vbnRobHksIGZpbGUgPSAiLi4vUmVzdWx0cy9JTl9OX01vbnRobHkuY3N2Iiwgcm93Lm5hbWVzID0gRkFMU0UpDQpgYGANCiMgQXRtb3NmIGRlcG9zaXRpb24NCmBgYHtyfQ0KRFdfTl9ZZWFybHkgPC0gZmlsdGVyKEVSX04sIEdyb3VwID09ICJEVyIsICFpcy5uYShFbWlzc2lvbikpICU+JQ0KICBsZWZ0X2pvaW4oQ2F0Y2htZW50X0VSLCAgYnkgPSAiQUlfY29kZSIpICU+JQ0KICBncm91cF9ieShJRCwgWWVhcikgJT4lDQogIHN1bW1hcmlzZShEV19OID0gc3VtKEVtaXNzaW9uLCBuYS5ybSA9IFRSVUUpLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUNCiAgc3ByZWFkKFllYXIsIERXX04pICU+JQ0KICBkcm9wX25hKCkgJT4lDQogIGFkZF9jb2x1bW4oIjIwMTIiID0gTkEsIC5hZnRlciA9ICIyMDEwIikgJT4lDQogIGFkZF9jb2x1bW4oIjIwMTEiID0gTkEsIC5hZnRlciA9ICIyMDEwIikgJT4lDQogIHBpdm90X2xvbmdlcihjb2xzID0gMjoxMSwgbmFtZXNfdG8gPSJZZWFyIiwgdmFsdWVzX3RvID0gIkRXX04iKSAlPiUNCiAgZ3JvdXBfYnkoSUQpICU+JQ0KICBtdXRhdGUoRFdfTiA9IGlmZWxzZShpcy5uYShEV19OKSwgbWVhbihEV19OLCBuYS5ybSA9IFRSVUUpLCBEV19OKSkNCndyaXRlLmNzdihEV19OX1llYXJseSwgZmlsZSA9ICIuLi9SZXN1bHRzL0RXX05fWWVhcmx5LmNzdiIsIHJvdy5uYW1lcyA9IEZBTFNFKQ0KYGBgDQpgYGB7cn0NCkRXX05fWWVhcmx5JFllYXIgPC0gYXMubnVtZXJpYyhEV19OX1llYXJseSRZZWFyKQ0KRFdfTl9Nb250aGx5IDwtIG11dGF0ZShEV19OX1llYXJseSwgRFdfTiA9IERXX04vMTIpDQpEV19OX01vbnRobHkgPC0gbGVmdF9qb2luKENhdGNobWVudF9UaW1lLCBEV19OX01vbnRobHksIGJ5ID0gYygiSUQiLCAiWWVhciIpKSAlPiUNCiAgcmVwbGFjZShpcy5uYSguKSwgMC4wKQ0Kd3JpdGUuY3N2KERXX05fTW9udGhseSwgZmlsZSA9ICIuLi9SZXN1bHRzL0RXX05fTW9udGhseS5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkNCmBgYA0KIyBPdmVyaWdlDQpgYGB7cn0NCk9SX05fWWVhcmx5IDwtIGZpbHRlcihFUl9OLCBHcm91cCA9PSAiT1IiLCAhaXMubmEoRW1pc3Npb24pKSAlPiUNCiAgbGVmdF9qb2luKENhdGNobWVudF9FUiwgIGJ5ID0gIkFJX2NvZGUiKSAlPiUNCiAgZ3JvdXBfYnkoSUQsIFllYXIpICU+JQ0KICBzdW1tYXJpc2UoT1JfTiA9IHN1bShFbWlzc2lvbiwgbmEucm0gPSBUUlVFKSwgLmdyb3VwcyA9ICJkcm9wIikgJT4lDQogIHNwcmVhZChZZWFyLCBPUl9OKSAlPiUNCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSAyOjExLCBuYW1lc190byA9IlllYXIiLCB2YWx1ZXNfdG8gPSAiT1JfTiIpICU+JQ0KICBncm91cF9ieShJRCkgJT4lDQogIG11dGF0ZShPUl9OID0gaWZlbHNlKGlzLm5hKE9SX04pLCBtZWFuKE9SX04sIG5hLnJtID0gVFJVRSksIE9SX04pKQ0Kd3JpdGUuY3N2KE9SX05fWWVhcmx5LCBmaWxlID0gIi4uL1Jlc3VsdHMvT1JfTl9ZZWFybHkuY3N2Iiwgcm93Lm5hbWVzID0gRkFMU0UpDQpgYGANCmBgYHtyfQ0KT1JfTl9ZZWFybHkkWWVhciA8LSBhcy5udW1lcmljKE9SX05fWWVhcmx5JFllYXIpDQpPUl9OX01vbnRobHkgPC0gbXV0YXRlKE9SX05fWWVhcmx5LCBPUl9OID0gT1JfTi8xMikNCk9SX05fTW9udGhseSA8LSBsZWZ0X2pvaW4oQ2F0Y2htZW50X1RpbWUsIE9SX05fTW9udGhseSwgYnkgPSBjKCJJRCIsICJZZWFyIikpICU+JQ0KICByZXBsYWNlKGlzLm5hKC4pLCAwLjApDQp3cml0ZS5jc3YoT1JfTl9Nb250aGx5LCBmaWxlID0gIi4uL1Jlc3VsdHMvT1JfTl9Nb250aGx5LmNzdiIsIHJvdy5uYW1lcyA9IEZBTFNFKQ0KYGBgDQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgIyBPdmVyaWdlIGxhbmRib3V3ZWVtaXNzaWVzDQojIFANCmBgYHtyfQ0KTE9fUF9ZZWFybHkgPC0gZmlsdGVyKEVSX1AsIEdyb3VwID09ICJMTyIsICFpcy5uYShFbWlzc2lvbikpICU+JQ0KICBsZWZ0X2pvaW4oQ2F0Y2htZW50X0VSLCAgYnkgPSAiQUlfY29kZSIpICU+JQ0KICBncm91cF9ieShJRCwgWWVhcikgJT4lDQogIHN1bW1hcmlzZShMT19QID0gc3VtKEVtaXNzaW9uLCBuYS5ybSA9IFRSVUUpLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUNCiAgc3ByZWFkKFllYXIsIExPX1ApICU+JQ0KICBwaXZvdF9sb25nZXIoY29scyA9IDI6MTEsIG5hbWVzX3RvID0iWWVhciIsIHZhbHVlc190byA9ICJMT19QIikgJT4lDQogIGdyb3VwX2J5KElEKSAlPiUNCiAgbXV0YXRlKExPX1AgPSBpZmVsc2UoaXMubmEoTE9fUCksIG1lYW4oTE9fUCwgbmEucm0gPSBUUlVFKSwgTE9fUCkpDQp3cml0ZS5jc3YoTE9fUF9ZZWFybHksIGZpbGUgPSAiLi4vUmVzdWx0cy9MT19QX1llYXJseS5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkNCmBgYA0KYGBge3J9DQpMT19QX1llYXJseSRZZWFyIDwtIGFzLm51bWVyaWMoTE9fUF9ZZWFybHkkWWVhcikNCkxPX1BfTW9udGhseSA8LSBtdXRhdGUoTE9fUF9ZZWFybHksIExPX1AgPSBMT19QLzEyKQ0KTE9fUF9Nb250aGx5IDwtIGxlZnRfam9pbihDYXRjaG1lbnRfVGltZSwgTE9fUF9Nb250aGx5LCBieSA9IGMoIklEIiwgIlllYXIiKSkgJT4lDQogIHJlcGxhY2UoaXMubmEoLiksIDAuMCkNCndyaXRlLmNzdihMT19QX01vbnRobHksIGZpbGUgPSAiLi4vUmVzdWx0cy9MT19QX01vbnRobHkuY3N2Iiwgcm93Lm5hbWVzID0gRkFMU0UpDQpgYGANCg0KIyBJbmR1c3RyeQ0KYGBge3J9DQpJTl9QX1llYXJseSA8LSBmaWx0ZXIoRVJfUCwgR3JvdXAgPT0gIklOIiwgIWlzLm5hKEVtaXNzaW9uKSkgJT4lDQogIGxlZnRfam9pbihDYXRjaG1lbnRfRVIsICBieSA9ICJBSV9jb2RlIikgJT4lDQogIGdyb3VwX2J5KElELCBZZWFyKSAlPiUNCiAgc3VtbWFyaXNlKElOX1AgPSBzdW0oRW1pc3Npb24sIG5hLnJtID0gVFJVRSksIC5ncm91cHMgPSAiZHJvcCIpICU+JQ0KICBzcHJlYWQoWWVhciwgSU5fUCkgJT4lDQogIHBpdm90X2xvbmdlcihjb2xzID0gMjoxMSwgbmFtZXNfdG8gPSJZZWFyIiwgdmFsdWVzX3RvID0gIklOX1AiKSAlPiUNCiAgZ3JvdXBfYnkoSUQpICU+JQ0KICBtdXRhdGUoSU5fUCA9IGlmZWxzZShpcy5uYShJTl9QKSwgbWVhbihJTl9QLCBuYS5ybSA9IFRSVUUpLCBJTl9QKSkNCndyaXRlLmNzdihJTl9QX1llYXJseSwgZmlsZSA9ICIuLi9SZXN1bHRzL0lOX1BfWWVhcmx5LmNzdiIsIHJvdy5uYW1lcyA9IEZBTFNFKQ0KYGBgDQpgYGB7cn0NCklOX1BfWWVhcmx5JFllYXIgPC0gYXMubnVtZXJpYyhJTl9QX1llYXJseSRZZWFyKQ0KSU5fUF9Nb250aGx5IDwtIG11dGF0ZShJTl9QX1llYXJseSwgSU5fUCA9IElOX1AvMTIpDQpJTl9QX01vbnRobHkgPC0gbGVmdF9qb2luKENhdGNobWVudF9UaW1lLCBJTl9QX01vbnRobHksIGJ5ID0gYygiSUQiLCAiWWVhciIpKSAlPiUNCiAgcmVwbGFjZShpcy5uYSguKSwgMC4wKQ0Kd3JpdGUuY3N2KElOX1BfTW9udGhseSwgZmlsZSA9ICIuLi9SZXN1bHRzL0lOX1BfTW9udGhseS5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkNCmBgYA0KIyBPdmVyaWdlDQpgYGB7cn0NCk9SX1BfWWVhcmx5IDwtIGZpbHRlcihFUl9QLCBHcm91cCA9PSAiT1IiLCAhaXMubmEoRW1pc3Npb24pKSAlPiUNCiAgbGVmdF9qb2luKENhdGNobWVudF9FUiwgIGJ5ID0gIkFJX2NvZGUiKSAlPiUNCiAgZ3JvdXBfYnkoSUQsIFllYXIpICU+JQ0KICBzdW1tYXJpc2UoT1JfUCA9IHN1bShFbWlzc2lvbiwgbmEucm0gPSBUUlVFKSwgLmdyb3VwcyA9ICJkcm9wIikgJT4lDQogIHNwcmVhZChZZWFyLCBPUl9QKSAlPiUNCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSAyOjExLCBuYW1lc190byA9IlllYXIiLCB2YWx1ZXNfdG8gPSAiT1JfUCIpICU+JQ0KICBncm91cF9ieShJRCkgJT4lDQogIG11dGF0ZShPUl9QID0gaWZlbHNlKGlzLm5hKE9SX1ApLCBtZWFuKE9SX1AsIG5hLnJtID0gVFJVRSksIE9SX1ApKQ0Kd3JpdGUuY3N2KE9SX1BfWWVhcmx5LCBmaWxlID0gIi4uL1Jlc3VsdHMvT1JfUF9ZZWFybHkuY3N2Iiwgcm93Lm5hbWVzID0gRkFMU0UpDQpgYGANCmBgYHtyfQ0KT1JfUF9ZZWFybHkkWWVhciA8LSBhcy5udW1lcmljKE9SX1BfWWVhcmx5JFllYXIpDQpPUl9QX01vbnRobHkgPC0gbXV0YXRlKE9SX1BfWWVhcmx5LCBPUl9QID0gT1JfUC8xMikNCk9SX1BfTW9udGhseSA8LSBsZWZ0X2pvaW4oQ2F0Y2htZW50X1RpbWUsIE9SX1BfTW9udGhseSwgYnkgPSBjKCJJRCIsICJZZWFyIikpICU+JQ0KICByZXBsYWNlKGlzLm5hKC4pLCAwLjApDQp3cml0ZS5jc3YoT1JfUF9Nb250aGx5LCBmaWxlID0gIi4uL1Jlc3VsdHMvT1JfUF9Nb250aGx5LmNzdiIsIHJvdy5uYW1lcyA9IEZBTFNFKQ0KYGBgDQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgOS4gSW5jb21pbmcgYW5kIERpc2NoYXJnZQ0KIyBCaWcgcml2ZXJzDQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgSW5sZXQgYW5kIERpc2NoYXJnZSBRLCBtMy9zDQpgYGB7cn0NCkluX091dF9sZXRfUSA8LSByZWFkX2NzdihDU1ZfSW5fT3V0X1EsIHNob3dfY29sX3R5cGVzID0gRkFMU0UpDQpgYGANCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgSW5sZXQgUQ0KYGBge3J9DQpJbmxldF9RX01vbnRobHkgPC0gSW5fT3V0X2xldF9RICU+JQ0KICBmaWx0ZXIoTG9jYXRpb24gJWluJSBjKCJFSUpTREdTIiwgIkxPQkgiLCAiU0NIQUFSVk9EREwiKSwgWWVhciAlaW4lIFlvSSkgJT4lDQogIGdyb3VwX2J5KExvY2F0aW9uLCBZZWFyLCBNb250aCkgJT4lDQogIHN1bW1hcmlzZShRID0gbWVhbihRLCBuYS5ybSA9IFRSVUUpLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUNCiAgbXV0YXRlKERheXMgPSBkYXlzX2luX21vbnRoKGFzLkRhdGUocGFzdGUoWWVhciwgTW9udGgsIjAxIiwgc2VwID0gIi0iKSkpLCBEaXNjaGFyZ2UgPSBRICogRGF5cyAqIDg2NDAwKSAlPiUNCiAgc2VsZWN0KExvY2F0aW9uLCBZZWFyLCBNb250aCwgRGlzY2hhcmdlKQ0KYGBgDQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgTixQLCBtZy9sDQpgYGB7cn0NCkluX091dF9OUCA8LSByZWFkX2NzdihDU1ZfSW5fT3V0X05QLCBzaG93X2NvbF90eXBlcyA9IEZBTFNFKQ0KYGBgDQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIEluY29taW5nIE4NCmBgYHtyfQ0KSW5sZXRfTl9Nb250aGx5IDwtIEluX091dF9OUCAlPiUNCiAgc2VsZWN0KExvY2F0aW9uLCBEYXksIE1vbnRoLCBZZWFyLCBQYXJhbWV0ZXIsIE1lYXN1cmVtZW50KSAlPiUNCiAgZmlsdGVyKFBhcmFtZXRlciAlaW4lIGMoInN0aWtzdG9mIEtqZWxkYWhsIiwgIm5pdHJhYXQiLCAibml0cmlldCIpLCBMb2NhdGlvbiAlaW4lIGMoIkVJSlNEUFROIiwgIkxPQlBUTiIsICJTQ0hBQVJWT0RETCIpLCBZZWFyICVpbiUgWW9JKSAlPiUNCiAgc3ByZWFkKFBhcmFtZXRlciwgTWVhc3VyZW1lbnQpICU+JQ0KICByZW5hbWUoTk8yID0gIm5pdHJpZXQiLCBOTzMgPSAibml0cmFhdCIsIE5LaiA9ICJzdGlrc3RvZiBLamVsZGFobCIpICU+JQ0KICBncm91cF9ieShMb2NhdGlvbiwgWWVhciwgTW9udGgpICU+JQ0KICBzdW1tYXJpc2UoYWNyb3NzKGMoTk8yLCBOTzMsIE5LaiksIG1lYW4sIG5hLnJtID0gVFJVRSksIC5ncm91cHMgPSAiZHJvcCIpICU+JQ0KICBtdXRhdGUoSW5sZXRfTiA9IDAuMDAxICogKE5LaiArIE5PMyArIE5PMikgKiBJbmxldF9RX01vbnRobHkkRGlzY2hhcmdlKSAlPiUNCiAgc2VsZWN0KExvY2F0aW9uLCBZZWFyLCBNb250aCwgSW5sZXRfTikNCg0KSW5sZXRfTG9icHRuMSA8LSBmaWx0ZXIoSW5sZXRfTl9Nb250aGx5LCBMb2NhdGlvbiA9PSAiTE9CUFROIikgJT4lDQogIG11dGF0ZShMb2NhdGlvbiA9ICJMT0JQVE4xIiwgSW5sZXRfTiA9IElubGV0X04gKiAwLjE1KQ0KSW5sZXRfTG9icHRuMiA8LSBmaWx0ZXIoSW5sZXRfTl9Nb250aGx5LCBMb2NhdGlvbiA9PSAiTE9CUFROIikgJT4lDQogIG11dGF0ZShMb2NhdGlvbiA9ICJMT0JQVE4yIiwgSW5sZXRfTiA9IElubGV0X04gKiAwLjg1KQ0KSW5sZXRfTl9Nb250aGx5IDwtIGZpbHRlcihJbmxldF9OX01vbnRobHksICFMb2NhdGlvbiA9PSAiTE9CUFROIikgJT4lDQogIGJpbmRfcm93cyhJbmxldF9Mb2JwdG4xLCBJbmxldF9Mb2JwdG4yKSAlPiUNCiAgbXV0YXRlKElEID0gY2FzZV93aGVuKExvY2F0aW9uID09ICAiTE9CUFROMSIgfiAxMDAyLA0KICAgICAgICAgICAgICAgICAgICAgICAgTG9jYXRpb24gPT0gICJMT0JQVE4yIiB+IDEwMDQsDQogICAgICAgICAgICAgICAgICAgICAgICBMb2NhdGlvbiA9PSAgIkVJSlNEUFROIiB+IDEwMDEsDQogICAgICAgICAgICAgICAgICAgICAgICBMb2NhdGlvbiA9PSAgIlNDSEFBUlZPRERMIiB+IDEwMDMpKQ0Kd3JpdGUuY3N2KElubGV0X05fTW9udGhseSwgZmlsZSA9ICIuLi9SZXN1bHRzL0lubGV0X0JpZ1JpdmVyc19OX01vbnRobHkuY3N2Iiwgcm93Lm5hbWVzID0gRkFMU0UpDQpgYGANCmBgYHtyfQ0KSW5sZXRfTl9ZZWFybHkgPC0gSW5sZXRfTl9Nb250aGx5ICU+JQ0KICBncm91cF9ieShJRCwgWWVhcikgJT4lDQogIHN1bW1hcmlzZShJbmxldF9OID0gc3VtKElubGV0X04sIG5hLnJtID0gVFJVRSksIC5ncm91cHMgPSAiZHJvcCIpDQp3cml0ZS5jc3YoSW5sZXRfTl9ZZWFybHksIGZpbGUgPSAiLi4vUmVzdWx0cy9JbmxldF9CaWdSaXZlcnNfTl9ZZWFybHkuY3N2Iiwgcm93Lm5hbWVzID0gRkFMU0UpDQpgYGANCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgSW5jb21pbmcgUA0KYGBge3J9DQpJbmxldF9QX01vbnRobHkgPC0gSW5fT3V0X05QICU+JQ0KICBzZWxlY3QoTG9jYXRpb24sIERheSwgTW9udGgsIFllYXIsIFBhcmFtZXRlciwgTWVhc3VyZW1lbnQpICU+JQ0KICBmaWx0ZXIoUGFyYW1ldGVyID09ICJmb3Nmb3IgdG90YWFsIiwgTG9jYXRpb24gJWluJSBjKCJFSUpTRFBUTiIsICJMT0JQVE4iLCAiU0NIQUFSVk9EREwiKSwgWWVhciAlaW4lIFlvSSkgJT4lDQogIGdyb3VwX2J5KExvY2F0aW9uLCBZZWFyLCBNb250aCkgJT4lDQogIHN1bW1hcmlzZShJbmxldF9QID0gbWVhbihNZWFzdXJlbWVudCwgbmEucm0gPSBUUlVFKSwgLmdyb3VwcyA9ICJkcm9wIikgJT4lDQogIG11dGF0ZShJbmxldF9QID0gMC4wMDEgKiBJbmxldF9QICogSW5sZXRfUV9Nb250aGx5JERpc2NoYXJnZSkgJT4lDQogIHNlbGVjdChMb2NhdGlvbiwgWWVhciwgTW9udGgsIElubGV0X1ApDQp3cml0ZS5jc3YoSW5sZXRfUF9Nb250aGx5LCBmaWxlID0gIi4uL1Jlc3VsdHMvSW5sZXRfQmlnUml2ZXJzX1BfTW9udGhseS5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkNCmBgYA0KYGBge3J9DQpJbmxldF9Mb2JwdG4xIDwtIGZpbHRlcihJbmxldF9QX01vbnRobHksIExvY2F0aW9uID09ICJMT0JQVE4iKSAlPiUNCiAgbXV0YXRlKExvY2F0aW9uID0gIkxPQlBUTjEiLCBJbmxldF9QID0gSW5sZXRfUCAqIDAuMTUpDQpJbmxldF9Mb2JwdG4yIDwtIGZpbHRlcihJbmxldF9QX01vbnRobHksIExvY2F0aW9uID09ICJMT0JQVE4iKSAlPiUNCiAgbXV0YXRlKExvY2F0aW9uID0gIkxPQlBUTjIiLCBJbmxldF9QID0gSW5sZXRfUCAqIDAuODUpDQpJbmxldF9QX01vbnRobHkgPC0gZmlsdGVyKElubGV0X1BfTW9udGhseSwgIUxvY2F0aW9uID09ICJMT0JQVE4iKSAlPiUNCiAgYmluZF9yb3dzKElubGV0X0xvYnB0bjEsIElubGV0X0xvYnB0bjIpICU+JQ0KICBtdXRhdGUoSUQgPSBjYXNlX3doZW4oTG9jYXRpb24gPT0gICJMT0JQVE4xIiB+IDEwMDIsDQogICAgICAgICAgICAgICAgICAgICAgICBMb2NhdGlvbiA9PSAgIkxPQlBUTjIiIH4gMTAwNCwNCiAgICAgICAgICAgICAgICAgICAgICAgIExvY2F0aW9uID09ICAiRUlKU0RQVE4iIH4gMTAwMSwNCiAgICAgICAgICAgICAgICAgICAgICAgIExvY2F0aW9uID09ICAiU0NIQUFSVk9EREwiIH4gMTAwMykpDQp3cml0ZS5jc3YoSW5sZXRfUF9Nb250aGx5LCBmaWxlID0gIi4uL1Jlc3VsdHMvSW5sZXRfQmlnUml2ZXJzX1BfTW9udGhseS5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkNCmBgYA0KYGBge3J9DQpJbmxldF9QX1llYXJseSA8LSBJbmxldF9QX01vbnRobHkgJT4lDQogIGdyb3VwX2J5KElELCBZZWFyKSAlPiUNCiAgc3VtbWFyaXNlKElubGV0X1AgPSBzdW0oSW5sZXRfUCwgbmEucm0gPSBUUlVFKSwgLmdyb3VwcyA9ICJkcm9wIikNCndyaXRlLmNzdihJbmxldF9QX1llYXJseSwgZmlsZSA9ICIuLi9SZXN1bHRzL0lubGV0X0JpZ1JpdmVyc19QX1llYXJseS5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkNCmBgYA0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgc21hbGwgc3RyZWFtcyBmcm9tIG5laWJvdXJpbmcgY291bnRyaWVzDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KYGBge3J9DQpDYXRjaG1lbnRfYnVpdGVubGFuZCA8LSByZWFkX2NzdihDU1ZfQ2F0Y2htZW50X2J1aXRlbmxhbmQsIHNob3dfY29sX3R5cGVzID0gRkFMU0UpICU+JQ0KICBmaWx0ZXIoc3RyX2RldGVjdChpbmxhYXQsICJCdWl0ZW5sYW5kIiksICFzdHJfZGV0ZWN0KGRlYmlldCwgIm9wIGJhc2lzIHZhbiB2cmFjaHRiZXBhbGluZyIpKSAlPiUNCiAgc2VsZWN0KElELCBkZWJpZXQsIGt3YWxpdGVpdCkNCmBgYA0KYGBge3J9DQpJTl9idWl0ZW5sYW5kX1FfTW9udGhseSA8LSByZWFkX2NzdihDU1ZfSU5fYnVpdGVubGFuZF9RX21lYW4sIHNob3dfY29sX3R5cGVzID0gRkFMU0UpICU+JQ0KICBmaWx0ZXIoWWVhciAlaW4lIFlvSSkgJT4lDQogIHBpdm90X2xvbmdlcihjb2xzID0gMzozNywgbmFtZXNfdG8gPSJkZWJpZXQiLCB2YWx1ZXNfdG8gPSAiUSIpICU+JQ0KICBtdXRhdGUoUSA9IGRheXNfaW5fbW9udGgoYXMuRGF0ZShwYXN0ZShZZWFyLCBNb250aCwiMDEiLCBzZXAgPSAiLSIpKSkgKiA4NjQwMCAqIFEpICU+JQ0KICBsZWZ0X2pvaW4oQ2F0Y2htZW50X2J1aXRlbmxhbmQsIGJ5ID0gImRlYmlldCIpDQpgYGANCiMgIHNlbGVjdChJRCwgWWVhciwgTW9udGgsIFEpDQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyBODQojIGRhdGEgYXMgY29uY2VudHJhdGlvbg0KYGBge3J9DQpJTl9idWl0ZW5sYW5kX05fTW9udGhseSA8LSByZWFkX2NzdihDU1ZfSU5fYnVpdGVubGFuZF9OX21lYW4sIHNob3dfY29sX3R5cGVzID0gRkFMU0UpICU+JQ0KICBmaWx0ZXIoWWVhciAlaW4lIFlvSSklPiUNCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSAzOjM3LCBuYW1lc190byA9ICJrd2FsaXRlaXQiLCB2YWx1ZXNfdG8gPSAiQkxfTiIpICU+JQ0KICBsZWZ0X2pvaW4oSU5fYnVpdGVubGFuZF9RX01vbnRobHksIGJ5ID0gYygiWWVhciIsICJNb250aCIsICJrd2FsaXRlaXQiKSkgJT4lDQogIGRyb3BfbmEoKSAlPiUNCiAgbXV0YXRlKEJMX04gPSBCTF9OICogUSAqIDAuMDAxKSAlPiUNCiAgZ3JvdXBfYnkoSUQsIFllYXIsIE1vbnRoKSAlPiUNCiAgc3VtbWFyaXNlKEJMX04gPSBzdW0oQkxfTiwgbmEucm0gPSBUUlVFKSwgLmdyb3VwcyA9ICJkcm9wIikNCmBgYA0KIyBkYXRhIGFzIHllYXJseSBOL1AsIGRpdmlkZWQgYnkgMTIgdG8gZ2V0IG1vbnRobHkNCmBgYHtyfQ0KSU5fYnVpdGVubGFuZF9OX01vbnRobHkyIDwtIHJlYWRfY3N2KENTVl9JTl9idWl0ZW5sYW5kX05fbWVhbjIsIHNob3dfY29sX3R5cGVzID0gRkFMU0UpDQpJTl9idWl0ZW5sYW5kX05fTW9udGhseTIgPC0gbGVmdF9qb2luKENhdGNobWVudF9UaW1lLCBJTl9idWl0ZW5sYW5kX05fTW9udGhseTIsIGJ5ID0gYygiSUQiLCAiWWVhciIpKSAlPiUNCiAgcmVwbGFjZShpcy5uYSguKSwgMC4wKQ0KYGBgDQpgYGB7cn0NCklOX2J1aXRlbmxhbmRfTl9Nb250aGx5IDwtIGxlZnRfam9pbihDYXRjaG1lbnRfVGltZSwgSU5fYnVpdGVubGFuZF9OX01vbnRobHksIGJ5ID0gYygiSUQiLCAiWWVhciIsICJNb250aCIpKSAlPiUNCiAgcmVwbGFjZShpcy5uYSguKSwgMC4wKSAlPiUNCiAgbXV0YXRlKEJMX04gPSBCTF9OICsgSU5fYnVpdGVubGFuZF9OX01vbnRobHkyJEJMX04pDQp3cml0ZS5jc3YoSU5fYnVpdGVubGFuZF9OX01vbnRobHksIGZpbGUgPSAiLi4vUmVzdWx0cy9JbmxldF9TbWFsbFJpdmVyc19OX01vbnRobHkuY3N2Iiwgcm93Lm5hbWVzID0gRkFMU0UpDQpgYGANCmBgYHtyfQ0KSU5fYnVpdGVubGFuZF9OX1llYXJseSA8LSBJTl9idWl0ZW5sYW5kX05fTW9udGhseSAlPiUNCiAgZ3JvdXBfYnkoSUQsIFllYXIpICU+JQ0KICBzdW1tYXJpc2UoQkxfTiA9IHN1bShCTF9OLCBuYS5ybSA9IFRSVUUpLCAuZ3JvdXBzID0gImRyb3AiKQ0Kd3JpdGUuY3N2KElOX2J1aXRlbmxhbmRfTl9ZZWFybHksIGZpbGUgPSAiLi4vUmVzdWx0cy9JbmxldF9TbWFsbFJpdmVyc19OX1llYXJseS5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkNCmBgYA0KIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgUA0KIyBkYXRhIGFzIGNvbmNlbnRyYXRpb24NCmBgYHtyfQ0KSU5fYnVpdGVubGFuZF9QX01vbnRobHkgPC0gcmVhZF9jc3YoQ1NWX0lOX2J1aXRlbmxhbmRfUF9tZWFuLCBzaG93X2NvbF90eXBlcyA9IEZBTFNFKSAlPiUNCiAgZmlsdGVyKFllYXIgJWluJSBZb0kpJT4lDQogIHBpdm90X2xvbmdlcihjb2xzID0gMzozNywgbmFtZXNfdG8gPSJrd2FsaXRlaXQiLCB2YWx1ZXNfdG8gPSAiQkxfUCIpICU+JQ0KICBsZWZ0X2pvaW4oSU5fYnVpdGVubGFuZF9RX01vbnRobHksIGJ5ID0gYygiWWVhciIsICJNb250aCIsICJrd2FsaXRlaXQiKSkgJT4lDQogIGRyb3BfbmEoKSAlPiUNCiAgbXV0YXRlKEJMX1AgPSBCTF9QICogUSAqIDAuMDAxKSAlPiUNCiAgZ3JvdXBfYnkoSUQsIFllYXIsIE1vbnRoKSAlPiUNCiAgc3VtbWFyaXNlKEJMX1AgPSBzdW0oQkxfUCwgbmEucm0gPSBUUlVFKSwgLmdyb3VwcyA9ICJkcm9wIikNCmBgYA0KIyBkYXRhIGFzIHllYXJseSBOL1AsIGRpdmlkZWQgYnkgMTIgdG8gZ2V0IG1vbnRobHkNCmBgYHtyfQ0KSU5fYnVpdGVubGFuZF9QX01vbnRobHkyIDwtIHJlYWRfY3N2KENTVl9JTl9idWl0ZW5sYW5kX1BfbWVhbjIsIHNob3dfY29sX3R5cGVzID0gRkFMU0UpDQpJTl9idWl0ZW5sYW5kX1BfTW9udGhseTIgPC0gbGVmdF9qb2luKENhdGNobWVudF9UaW1lLCBJTl9idWl0ZW5sYW5kX1BfTW9udGhseTIsIGJ5ID0gYygiSUQiLCAiWWVhciIpKSAlPiUNCiAgcmVwbGFjZShpcy5uYSguKSwgMC4wKQ0KYGBgDQpgYGB7cn0NCklOX2J1aXRlbmxhbmRfUF9Nb250aGx5IDwtIGxlZnRfam9pbihDYXRjaG1lbnRfVGltZSwgSU5fYnVpdGVubGFuZF9QX01vbnRobHksIGJ5ID0gYygiSUQiLCAiWWVhciIsICJNb250aCIpKSAlPiUNCiAgcmVwbGFjZShpcy5uYSguKSwgMC4wKSAlPiUNCiAgbXV0YXRlKEJMX1AgPSBCTF9QICsgSU5fYnVpdGVubGFuZF9QX01vbnRobHkyJEJMX1ApDQp3cml0ZS5jc3YoSU5fYnVpdGVubGFuZF9QX01vbnRobHksIGZpbGUgPSAiLi4vUmVzdWx0cy9JbmxldF9TbWFsbFJpdmVyc19QX01vbnRobHkuY3N2Iiwgcm93Lm5hbWVzID0gRkFMU0UpDQpgYGANCmBgYHtyfQ0KSU5fYnVpdGVubGFuZF9QX1llYXJseSA8LSBJTl9idWl0ZW5sYW5kX1BfTW9udGhseSAlPiUNCiAgZ3JvdXBfYnkoSUQsIFllYXIpICU+JQ0KICBzdW1tYXJpc2UoQkxfUCA9IHN1bShCTF9QLCBuYS5ybSA9IFRSVUUpLCAuZ3JvdXBzID0gImRyb3AiKQ0Kd3JpdGUuY3N2KElOX2J1aXRlbmxhbmRfUF9ZZWFybHksIGZpbGUgPSAiLi4vUmVzdWx0cy9JbmxldF9TbWFsbFJpdmVyc19QX1llYXJseS5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkNCmBgYA0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgcHJlcGFyZSBkYXRhIGZvciBpbi1sYW5kIHJvdXRpbmcNCiMgUmV0ZW50aW9uDQojIFUmQQ0KYGBge3J9DQpTb2lsIDwtIGFzLmRhdGEuZnJhbWUocmVhZF9kZWxpbShUWFRfU29pbCwgc2hvd19jb2xfdHlwZXMgPSBGQUxTRSkpDQpgYGANCmBgYHtyfQ0KUmV0ZW50aW9uX1VBX04gPC0gU29pbCAlPiUNCiAgbXV0YXRlKFJldF9BYnNvbHV0ZV9TdW1tZXIgPSBjYXNlX3doZW4oVFlQRUFFID09ICJwb2xkZXIiICYgQm9kZW0gPT0iS2xlaSIgfiBPV19zdW1tZXJfaW5jbF9oYSAqIDEwICogTl9SZXRfS2xlaV9TdW1tZXJfZ05tMiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFlQRUFFID09ICJwb2xkZXIiICYgQm9kZW0gPT0iVmVlbiIgfiBPV19zdW1tZXJfaW5jbF9oYSAqIDEwICogTl9SZXRfVmVlbl9TdW1tZXJfZ05tMiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSB+IDFlMTAwKSkgJT4lDQogIG11dGF0ZShSZXRfQWJzb2x1dGVfV2ludGVyID0gY2FzZV93aGVuKFRZUEVBRSA9PSAicG9sZGVyIiAmIEJvZGVtID09IktsZWkiIH4gT1dfd2ludGVyX2luY2xfaGEgKiAxMCAqIE5fUmV0X0tsZWlfV2ludGVyX2dObTIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRZUEVBRSA9PSAicG9sZGVyIiAmIEJvZGVtID09IlZlZW4iIH4gT1dfd2ludGVyX2luY2xfaGEgKiAxMCAqIE5fUmV0X1ZlZW5fV2ludGVyX2dObTIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUgfiAxZTEwMCkpICU+JQ0KICBtdXRhdGUoUmV0X0ZyYWN0aW9uX1N1bW1lciA9IGNhc2Vfd2hlbihUWVBFQUUgPT0gInZyaWogYWZ3YXRlcmVuZCIgfiBwbWluKE5fYV9TdW1tZXIgKiAoQWZ2U19tM3MgLyBPV19zdW1tZXJfZXhjbF9oYSkgXiBOX2JfU3VtbWVyLCAwLjkpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUWVBFQUUgPT0gInBvbGRlciIgJiBCb2RlbSAlaW4lIGMoIktsZWkiLCAiVmVlbiIpIH4gMC45LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUlVFIH4gMC41KSkgJT4lDQogIG11dGF0ZShSZXRfRnJhY3Rpb25fV2ludGVyID0gY2FzZV93aGVuKFRZUEVBRSA9PSAidnJpaiBhZndhdGVyZW5kIiB+IHBtaW4oTl9hX1dpbnRlciAqIChBZnZTX20zcyAvIE9XX3dpbnRlcl9leGNsX2hhKSBeIE5fYl9XaW50ZXIsIDAuOSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRZUEVBRSA9PSAicG9sZGVyIiAmIEJvZGVtICVpbiUgYygiS2xlaSIsICJWZWVuIikgfiAwLjksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUgfiAwLjUpKSAlPiUNCiAgc2VsZWN0KElELCBSZXRfQWJzb2x1dGVfU3VtbWVyLCBSZXRfQWJzb2x1dGVfV2ludGVyLCBSZXRfRnJhY3Rpb25fU3VtbWVyLCBSZXRfRnJhY3Rpb25fV2ludGVyKQ0KYGBgDQpgYGB7cn0NClJldGVudGlvbl9VQV9QIDwtIFNvaWwgJT4lDQogIG11dGF0ZShSZXRfRnJhY3Rpb25fU3VtbWVyID0gY2FzZV93aGVuKFRZUEVBRSA9PSAidnJpaiBhZndhdGVyZW5kIiB+IHBtaW4oUF9hX1N1bW1lciAqIChBZnZTX20zcyAvIE9XX3N1bW1lcl9leGNsX2hhKSBeIFBfYl9TdW1tZXIsIDAuOSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUgfiAwLjUpKSAlPiUNCiAgbXV0YXRlKFJldF9GcmFjdGlvbl9XaW50ZXIgPSBjYXNlX3doZW4oVFlQRUFFID09ICJ2cmlqIGFmd2F0ZXJlbmQiIH4gcG1pbihQX2FfV2ludGVyICogKEFmdlNfbTNzIC8gT1dfd2ludGVyX2V4Y2xfaGEpIF4gUF9iX1dpbnRlciwgMC45KSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSB+IDAuNSkpICU+JQ0KICBzZWxlY3QoSUQsIFJldF9GcmFjdGlvbl9TdW1tZXIsIFJldF9GcmFjdGlvbl9XaW50ZXIpDQpgYGANCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIHJldGVudGlvbiBmcmFjdGlvbiBvdmVyaWdlDQpgYGB7cn0NClJldGVudGlvbl9GcmFfRVJfTiA8LSBTb2lsICU+JQ0KICBtdXRhdGUoUmV0X0ZyYWN0aW9uID0gY2FzZV93aGVuKFRZUEVBRSA9PSAicG9sZGVyIiAmIEJvZGVtICVpbiUgYygiS2xlaSIsICJWZWVuIikgfiAwLjAsIFRSVUUgfiAwLjIpKSAlPiUNCiAgc2VsZWN0KElELFJldF9GcmFjdGlvbikNCmBgYA0KYGBge3J9DQpSZXRlbnRpb25fRnJhX0VSX1AgPC0gU29pbCAlPiUNCiAgbXV0YXRlKFJldF9GcmFjdGlvbiA9IDAuMikgJT4lDQogIHNlbGVjdChJRCxSZXRfRnJhY3Rpb24pDQpgYGANCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgQ2F0Y2htZW50IHJvdXRpbmcNCmBgYHtyfQ0KUm91dGluZ181MzggPC0gYXMuZGF0YS5mcmFtZShyZWFkX2RlbGltKFRYVF9Sb3V0aW5nX1NUT05FLCBzaG93X2NvbF90eXBlcyA9IEZBTFNFKSkgJT4lDQogIHJlbmFtZSgiSUQiID0gIkZST00iKSAjZnJvbSBpZCwgdG8gMSwgd2VpZ2h0IDEsIHRvIDIsIHdlaWdodCAyLCB0byAzLCB3ZWlnaHQgMw0KYGBgDQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIFVBLCByZXRlbnRpb24gc29pbCBzcGVjaWZpYw0KYGBge3J9DQpSb3V0aW5nX1N0b25lX04gPC0gU3RvbmVfTl9Nb250aGx5ICU+JQ0KICBsZWZ0X2pvaW4oUmV0ZW50aW9uX1VBX04sIGJ5ID0gIklEIikgJT4lDQogIHRyYW5zbXV0ZShJRCA9IElELCBZZWFyID0gWWVhciwgTW9udGggPSBNb250aCwgU3RvbmVfTiA9IFN0b25lX04sDQogICAgICAgICAgICBSZXRfQWJzb2x1dGUgPSBjYXNlX3doZW4oTW9udGggJWluJSA0OjkgfiBSZXRfQWJzb2x1dGVfU3VtbWVyLCBUUlVFIH4gUmV0X0Fic29sdXRlX1dpbnRlciksDQogICAgICAgICAgICBSZXRfRnJhY3Rpb24gPSBjYXNlX3doZW4oTW9udGggJWluJSA0OjkgfiBSZXRfRnJhY3Rpb25fU3VtbWVyLCBUUlVFIH4gUmV0X0ZyYWN0aW9uX1dpbnRlcikpDQpgYGANCmBgYHtyfQ0KUm91dGluZ19TdG9uZV9QIDwtIFN0b25lX1BfTW9udGhseSAlPiUNCiAgbGVmdF9qb2luKFJldGVudGlvbl9VQV9QLCBieSA9ICJJRCIpICU+JQ0KICB0cmFuc211dGUoSUQgPSBJRCwgWWVhciA9IFllYXIsIE1vbnRoID0gTW9udGgsIFN0b25lX1AgPSBTdG9uZV9QLA0KICAgICAgICAgICAgUmV0X0ZyYWN0aW9uID0gY2FzZV93aGVuKE1vbnRoICVpbiUgNDo5IH4gUmV0X0ZyYWN0aW9uX1N1bW1lciwgVFJVRSB+IFJldF9GcmFjdGlvbl9XaW50ZXIpKQ0KYGBgDQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIEVSICsgQnVpdGVubGFuZCwgcmV0ZW50aW9uIDAuMCAtIDAuMg0KYGBge3J9DQpSb3V0aW5nX0xPX04gPC0gTE9fTl9Nb250aGx5ICU+JQ0KICBsZWZ0X2pvaW4oUmV0ZW50aW9uX0ZyYV9FUl9OLCBieSA9ICJJRCIpDQpSb3V0aW5nX0lOX04gPC0gSU5fTl9Nb250aGx5ICU+JQ0KICBsZWZ0X2pvaW4oUmV0ZW50aW9uX0ZyYV9FUl9OLCBieSA9ICJJRCIpDQpSb3V0aW5nX09SX04gPC0gT1JfTl9Nb250aGx5ICU+JQ0KICBsZWZ0X2pvaW4oUmV0ZW50aW9uX0ZyYV9FUl9OLCBieSA9ICJJRCIpDQpSb3V0aW5nX0RXX04gPC0gRFdfTl9Nb250aGx5ICU+JQ0KICBsZWZ0X2pvaW4oUmV0ZW50aW9uX0ZyYV9FUl9OLCBieSA9ICJJRCIpDQpSb3V0aW5nX1JXWklfTiA8LSBSV1pJX05fTW9udGhseSAlPiUNCiAgbGVmdF9qb2luKFJldGVudGlvbl9GcmFfRVJfTiwgYnkgPSAiSUQiKQ0KUm91dGluZ19CTF9OIDwtIElOX2J1aXRlbmxhbmRfTl9Nb250aGx5ICU+JQ0KICBsZWZ0X2pvaW4oUmV0ZW50aW9uX0ZyYV9FUl9OLCBieSA9ICJJRCIpDQoNClJvdXRpbmdfTE9fUCA8LSBMT19QX01vbnRobHkgJT4lDQogIGxlZnRfam9pbihSZXRlbnRpb25fRnJhX0VSX1AsIGJ5ID0gIklEIikNClJvdXRpbmdfSU5fUCA8LSBJTl9QX01vbnRobHkgJT4lDQogIGxlZnRfam9pbihSZXRlbnRpb25fRnJhX0VSX1AsIGJ5ID0gIklEIikNClJvdXRpbmdfT1JfUCA8LSBPUl9QX01vbnRobHkgJT4lDQogIGxlZnRfam9pbihSZXRlbnRpb25fRnJhX0VSX1AsIGJ5ID0gIklEIikNClJvdXRpbmdfUldaSV9QIDwtIFJXWklfUF9Nb250aGx5ICU+JQ0KICBsZWZ0X2pvaW4oUmV0ZW50aW9uX0ZyYV9FUl9QLCBieSA9ICJJRCIpDQpSb3V0aW5nX0JMX1AgPC0gSU5fYnVpdGVubGFuZF9QX01vbnRobHkgJT4lDQogIGxlZnRfam9pbihSZXRlbnRpb25fRnJhX0VSX1AsIGJ5ID0gIklEIikNCg0KUm91dGluZ19FUl9OIDwtIENhdGNobWVudF9UaW1lICU+JQ0KICBsZWZ0X2pvaW4oTE9fTl9Nb250aGx5LCBieSA9IGMoIklEIiwgIlllYXIiLCAiTW9udGgiKSkgJT4lDQogIGxlZnRfam9pbihJTl9OX01vbnRobHksIGJ5ID0gYygiSUQiLCAiWWVhciIsICJNb250aCIpKSAlPiUNCiAgbGVmdF9qb2luKE9SX05fTW9udGhseSwgYnkgPSBjKCJJRCIsICJZZWFyIiwgIk1vbnRoIikpICU+JQ0KICBsZWZ0X2pvaW4oRFdfTl9Nb250aGx5LCBieSA9IGMoIklEIiwgIlllYXIiLCAiTW9udGgiKSkgJT4lDQogIGxlZnRfam9pbihSV1pJX05fTW9udGhseSwgYnkgPSBjKCJJRCIsICJZZWFyIiwgIk1vbnRoIikpICU+JQ0KICBsZWZ0X2pvaW4oSU5fYnVpdGVubGFuZF9OX01vbnRobHksIGJ5ID0gYygiSUQiLCAiWWVhciIsICJNb250aCIpKSAlPiUNCiAgdHJhbnNtdXRlKElEID0gSUQsIFllYXIgPSBZZWFyLCBNb250aCA9IE1vbnRoLCBFUl9OID0gTE9fTiArIElOX04gKyBPUl9OICsgRFdfTiArIFJXWklfTiArIEJMX04pICU+JQ0KICBsZWZ0X2pvaW4oUmV0ZW50aW9uX0ZyYV9FUl9OLCBieSA9ICJJRCIpDQoNClJvdXRpbmdfRVJfUCA8LSBDYXRjaG1lbnRfVGltZSAlPiUNCiAgbGVmdF9qb2luKExPX1BfTW9udGhseSwgYnkgPSBjKCJJRCIsICJZZWFyIiwgIk1vbnRoIikpICU+JQ0KICBsZWZ0X2pvaW4oSU5fUF9Nb250aGx5LCBieSA9IGMoIklEIiwgIlllYXIiLCAiTW9udGgiKSkgJT4lDQogIGxlZnRfam9pbihPUl9QX01vbnRobHksIGJ5ID0gYygiSUQiLCAiWWVhciIsICJNb250aCIpKSAlPiUNCiAgbGVmdF9qb2luKFJXWklfUF9Nb250aGx5LCBieSA9IGMoIklEIiwgIlllYXIiLCAiTW9udGgiKSkgJT4lDQogIGxlZnRfam9pbihJTl9idWl0ZW5sYW5kX1BfTW9udGhseSwgYnkgPSBjKCJJRCIsICJZZWFyIiwgIk1vbnRoIikpICU+JQ0KICB0cmFuc211dGUoSUQgPSBJRCwgWWVhciA9IFllYXIsIE1vbnRoID0gTW9udGgsIEVSX1AgPSBMT19QICsgT1JfUCArIElOX1AgKyBSV1pJX1AgKyBCTF9QKSAlPiUNCiAgbGVmdF9qb2luKFJldGVudGlvbl9GcmFfRVJfUCwgYnkgPSAiSUQiKQ0KYGBgDQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIGxvb3AgYmVnaW5zIGhlcmUNCmBgYHtyfQ0KUm91dGluZyA8LSBSb3V0aW5nXzUzOA0KZm9yIChMZXZlbCBpbiAxOjcpICMgbG9vcCBmcm9tIHRoZSBzbWFsbGVzdCByaXZlciB0byBsYXJnZSBvbmVzDQp7DQogIFJvdXRpbmdfU3RvbmVfTiA8LSBtdXRhdGUoUm91dGluZ19TdG9uZV9OLCBSZXRfU3RvbmVfTiA9IFN0b25lX04gKiBSZXRfRnJhY3Rpb24pICU+JQ0KICAgIG11dGF0ZShSZXRfU3RvbmVfTiA9IGlmX2Vsc2UoUmV0X1N0b25lX04gPCBSZXRfQWJzb2x1dGUsIFJldF9TdG9uZV9OLCBSZXRfQWJzb2x1dGUpLCBBZndlbnRlbGluZyA9IFN0b25lX04gLSBSZXRfU3RvbmVfTikNCiAgUm91dGluZ19TdG9uZV9QIDwtIG11dGF0ZShSb3V0aW5nX1N0b25lX1AsIFJldF9TdG9uZV9QID0gU3RvbmVfUCAqIFJldF9GcmFjdGlvbiwgQWZ3ZW50ZWxpbmcgPSBTdG9uZV9QIC0gUmV0X1N0b25lX1ApDQoNCiAgUm91dGluZ19FUl9OIDwtIG11dGF0ZShSb3V0aW5nX0VSX04sIFJldF9FUl9OID0gRVJfTiAqIFJldF9GcmFjdGlvbiwgQWZ3ZW50ZWxpbmcgPSBFUl9OIC0gUmV0X0VSX04pDQogIFJvdXRpbmdfRVJfUCA8LSBtdXRhdGUoUm91dGluZ19FUl9QLCBSZXRfRVJfUCA9IEVSX1AgKiBSZXRfRnJhY3Rpb24sIEFmd2VudGVsaW5nID0gRVJfUCAtIFJldF9FUl9QKQ0KDQogIFJvdXRpbmdfTE9fTiA8LSBtdXRhdGUoUm91dGluZ19MT19OLCBSZXRfTE9fTiA9IExPX04gKiBSZXRfRnJhY3Rpb24sIEFmd2VudGVsaW5nID0gTE9fTiAtIFJldF9MT19OKQ0KICBSb3V0aW5nX0xPX1AgPC0gbXV0YXRlKFJvdXRpbmdfTE9fUCwgUmV0X0xPX1AgPSBMT19QICogUmV0X0ZyYWN0aW9uLCBBZndlbnRlbGluZyA9IExPX1AgLSBSZXRfTE9fUCkNCg0KICBSb3V0aW5nX0lOX04gPC0gbXV0YXRlKFJvdXRpbmdfSU5fTiwgUmV0X0lOX04gPSBJTl9OICogUmV0X0ZyYWN0aW9uLCBBZndlbnRlbGluZyA9IElOX04gLSBSZXRfSU5fTikNCiAgUm91dGluZ19JTl9QIDwtIG11dGF0ZShSb3V0aW5nX0lOX1AsIFJldF9JTl9QID0gSU5fUCAqIFJldF9GcmFjdGlvbiwgQWZ3ZW50ZWxpbmcgPSBJTl9QIC0gUmV0X0lOX1ApDQoNCiAgUm91dGluZ19EV19OIDwtIG11dGF0ZShSb3V0aW5nX0RXX04sIFJldF9EV19OID0gRFdfTiAqIFJldF9GcmFjdGlvbiwgQWZ3ZW50ZWxpbmcgPSBEV19OIC0gUmV0X0RXX04pDQoNCiAgUm91dGluZ19PUl9OIDwtIG11dGF0ZShSb3V0aW5nX09SX04sIFJldF9PUl9OID0gT1JfTiAqIFJldF9GcmFjdGlvbiwgQWZ3ZW50ZWxpbmcgPSBPUl9OIC0gUmV0X09SX04pDQogIFJvdXRpbmdfT1JfUCA8LSBtdXRhdGUoUm91dGluZ19PUl9QLCBSZXRfT1JfUCA9IE9SX1AgKiBSZXRfRnJhY3Rpb24sIEFmd2VudGVsaW5nID0gT1JfUCAtIFJldF9PUl9QKQ0KDQogIFJvdXRpbmdfUldaSV9OIDwtIG11dGF0ZShSb3V0aW5nX1JXWklfTiwgUmV0X1JXWklfTiA9IFJXWklfTiAqIFJldF9GcmFjdGlvbiwgQWZ3ZW50ZWxpbmcgPSBSV1pJX04gLSBSZXRfUldaSV9OKQ0KICBSb3V0aW5nX1JXWklfUCA8LSBtdXRhdGUoUm91dGluZ19SV1pJX1AsIFJldF9SV1pJX1AgPSBSV1pJX1AgKiBSZXRfRnJhY3Rpb24sIEFmd2VudGVsaW5nID0gUldaSV9QIC0gUmV0X1JXWklfUCkNCg0KICBSb3V0aW5nX0JMX04gPC0gbXV0YXRlKFJvdXRpbmdfQkxfTiwgUmV0X0JMX04gPSBCTF9OICogUmV0X0ZyYWN0aW9uLCBBZndlbnRlbGluZyA9IEJMX04gLSBSZXRfQkxfTikNCiAgUm91dGluZ19CTF9QIDwtIG11dGF0ZShSb3V0aW5nX0JMX1AsIFJldF9CTF9QID0gQkxfUCAqIFJldF9GcmFjdGlvbiwgQWZ3ZW50ZWxpbmcgPSBCTF9QIC0gUmV0X0JMX1ApDQoNCg0KICBVcHBlciA8LSBmaWx0ZXIoUm91dGluZywgIUlEICVpbiUgYyhUT18xLCBUT18yLCBUT18zKSkgIyBkb2VzIG5vdCByZWNlaXZlIHdhdGVyIGZyb20gb3RoZXIgY2F0Y2htZW50DQogIGZvciAoaSBpbiAxOm5yb3coVXBwZXIpKQ0KICB7DQogICAgIyBTdG9uZSBODQogICAgTl9TdG9uZV9mcm9tIDwtIGZpbHRlcihSb3V0aW5nX1N0b25lX04sIElEID09IFVwcGVyW2ksMV0pICMgZnJvbQ0KICAgIE5fU3RvbmVfdG9fMSA8LSBmaWx0ZXIoUm91dGluZ19TdG9uZV9OLCBJRCA9PSBVcHBlcltpLDJdKSAlPiUNCiAgICAgIG11dGF0ZShTdG9uZV9OID0gTl9TdG9uZV9mcm9tJEFmd2VudGVsaW5nICogVXBwZXJbaSwzXSkgJT4lDQogICAgICBzZWxlY3QoSUQsIFllYXIsIE1vbnRoLCBTdG9uZV9OKQ0KICAgIE5fU3RvbmVfdG9fMSA8LSBsZWZ0X2pvaW4oQ2F0Y2htZW50X1RpbWUsIE5fU3RvbmVfdG9fMSwgYnkgPSBjKCJJRCIsICJZZWFyIiwgIk1vbnRoIikpICU+JQ0KICAgICAgcmVwbGFjZShpcy5uYSguKSwgMC4wKQ0KICAgIFJvdXRpbmdfU3RvbmVfTiA8LSBtdXRhdGUoUm91dGluZ19TdG9uZV9OLCBTdG9uZV9OID0gU3RvbmVfTiArIE5fU3RvbmVfdG9fMSRTdG9uZV9OKQ0KDQogICAgIyBUb3RhbCBFUiArIEJMIE4NCiAgICBOX0VSX2Zyb20gPC0gZmlsdGVyKFJvdXRpbmdfRVJfTiwgSUQgPT0gVXBwZXJbaSwxXSkgIyBmcm9tDQogICAgTl9FUl90b18xIDwtIGZpbHRlcihSb3V0aW5nX0VSX04sIElEID09IFVwcGVyW2ksMl0pICU+JQ0KICAgICAgbXV0YXRlKEVSX04gPSBOX0VSX2Zyb20kQWZ3ZW50ZWxpbmcgKiBVcHBlcltpLDNdKSAlPiUNCiAgICAgIHNlbGVjdChJRCwgWWVhciwgTW9udGgsIEVSX04pDQogICAgTl9FUl90b18xIDwtIGxlZnRfam9pbihDYXRjaG1lbnRfVGltZSwgTl9FUl90b18xLCBieSA9IGMoIklEIiwgIlllYXIiLCAiTW9udGgiKSkgJT4lDQogICAgICByZXBsYWNlKGlzLm5hKC4pLCAwLjApDQogICAgUm91dGluZ19FUl9OIDwtIG11dGF0ZShSb3V0aW5nX0VSX04sIEVSX04gPSBFUl9OICsgTl9FUl90b18xJEVSX04pDQoNCiAgICAjIFN0b25lIFANCiAgICBQX1N0b25lX2Zyb20gPC0gZmlsdGVyKFJvdXRpbmdfU3RvbmVfUCwgSUQgPT0gVXBwZXJbaSwxXSkgIyBmcm9tDQogICAgUF9TdG9uZV90b18xIDwtIGZpbHRlcihSb3V0aW5nX1N0b25lX1AsIElEID09IFVwcGVyW2ksMl0pICU+JQ0KICAgICAgbXV0YXRlKFN0b25lX1AgPSBQX1N0b25lX2Zyb20kQWZ3ZW50ZWxpbmcgKiBVcHBlcltpLDNdKSAlPiUNCiAgICAgIHNlbGVjdChJRCwgWWVhciwgTW9udGgsIFN0b25lX1ApDQogICAgUF9TdG9uZV90b18xIDwtIGxlZnRfam9pbihDYXRjaG1lbnRfVGltZSwgUF9TdG9uZV90b18xLCBieSA9IGMoIklEIiwgIlllYXIiLCAiTW9udGgiKSkgJT4lDQogICAgICByZXBsYWNlKGlzLm5hKC4pLCAwLjApDQogICAgUm91dGluZ19TdG9uZV9QIDwtIG11dGF0ZShSb3V0aW5nX1N0b25lX1AsIFN0b25lX1AgPSBTdG9uZV9QICsgUF9TdG9uZV90b18xJFN0b25lX1ApDQoNCiAgICAjIFRvdGFsIEVSICsgQkwgUA0KICAgIFBfRVJfZnJvbSA8LSBmaWx0ZXIoUm91dGluZ19FUl9QLCBJRCA9PSBVcHBlcltpLDFdKSAjIGZyb20NCiAgICBQX0VSX3RvXzEgPC0gZmlsdGVyKFJvdXRpbmdfRVJfUCwgSUQgPT0gVXBwZXJbaSwyXSkgJT4lDQogICAgICBtdXRhdGUoRVJfUCA9IFBfRVJfZnJvbSRBZndlbnRlbGluZyAqIFVwcGVyW2ksM10pICU+JQ0KICAgICAgc2VsZWN0KElELCBZZWFyLCBNb250aCwgRVJfUCkNCiAgICBQX0VSX3RvXzEgPC0gbGVmdF9qb2luKENhdGNobWVudF9UaW1lLCBQX0VSX3RvXzEsIGJ5ID0gYygiSUQiLCAiWWVhciIsICJNb250aCIpKSAlPiUNCiAgICAgIHJlcGxhY2UoaXMubmEoLiksIDAuMCkNCiAgICBSb3V0aW5nX0VSX1AgPC0gbXV0YXRlKFJvdXRpbmdfRVJfUCwgRVJfUCA9IEVSX1AgKyBQX0VSX3RvXzEkRVJfUCkNCg0KICAgICMgVG90YWwgTE8gKyBCTCBODQogICAgTl9MT19mcm9tIDwtIGZpbHRlcihSb3V0aW5nX0xPX04sIElEID09IFVwcGVyW2ksMV0pICMgZnJvbQ0KICAgIE5fTE9fdG9fMSA8LSBmaWx0ZXIoUm91dGluZ19MT19OLCBJRCA9PSBVcHBlcltpLDJdKSAlPiUNCiAgICAgIG11dGF0ZShMT19OID0gTl9MT19mcm9tJEFmd2VudGVsaW5nICogVXBwZXJbaSwzXSkgJT4lDQogICAgICBzZWxlY3QoSUQsIFllYXIsIE1vbnRoLCBMT19OKQ0KICAgIE5fTE9fdG9fMSA8LSBsZWZ0X2pvaW4oQ2F0Y2htZW50X1RpbWUsIE5fTE9fdG9fMSwgYnkgPSBjKCJJRCIsICJZZWFyIiwgIk1vbnRoIikpICU+JQ0KICAgICAgcmVwbGFjZShpcy5uYSguKSwgMC4wKQ0KICAgIFJvdXRpbmdfTE9fTiA8LSBtdXRhdGUoUm91dGluZ19MT19OLCBMT19OID0gTE9fTiArIE5fTE9fdG9fMSRMT19OKQ0KDQogICAgIyBUb3RhbCBMTyArIEJMIFANCiAgICBQX0xPX2Zyb20gPC0gZmlsdGVyKFJvdXRpbmdfTE9fUCwgSUQgPT0gVXBwZXJbaSwxXSkgIyBmcm9tDQogICAgUF9MT190b18xIDwtIGZpbHRlcihSb3V0aW5nX0xPX1AsIElEID09IFVwcGVyW2ksMl0pICU+JQ0KICAgICAgbXV0YXRlKExPX1AgPSBQX0xPX2Zyb20kQWZ3ZW50ZWxpbmcgKiBVcHBlcltpLDNdKSAlPiUNCiAgICAgIHNlbGVjdChJRCwgWWVhciwgTW9udGgsIExPX1ApDQogICAgUF9MT190b18xIDwtIGxlZnRfam9pbihDYXRjaG1lbnRfVGltZSwgUF9MT190b18xLCBieSA9IGMoIklEIiwgIlllYXIiLCAiTW9udGgiKSkgJT4lDQogICAgICByZXBsYWNlKGlzLm5hKC4pLCAwLjApDQogICAgUm91dGluZ19MT19QIDwtIG11dGF0ZShSb3V0aW5nX0xPX1AsIExPX1AgPSBMT19QICsgUF9MT190b18xJExPX1ApDQoNCiAgICAjIFRvdGFsIElOICsgQkwgTg0KICAgIE5fSU5fZnJvbSA8LSBmaWx0ZXIoUm91dGluZ19JTl9OLCBJRCA9PSBVcHBlcltpLDFdKSAjIGZyb20NCiAgICBOX0lOX3RvXzEgPC0gZmlsdGVyKFJvdXRpbmdfSU5fTiwgSUQgPT0gVXBwZXJbaSwyXSkgJT4lDQogICAgICBtdXRhdGUoSU5fTiA9IE5fSU5fZnJvbSRBZndlbnRlbGluZyAqIFVwcGVyW2ksM10pICU+JQ0KICAgICAgc2VsZWN0KElELCBZZWFyLCBNb250aCwgSU5fTikNCiAgICBOX0lOX3RvXzEgPC0gbGVmdF9qb2luKENhdGNobWVudF9UaW1lLCBOX0lOX3RvXzEsIGJ5ID0gYygiSUQiLCAiWWVhciIsICJNb250aCIpKSAlPiUNCiAgICAgIHJlcGxhY2UoaXMubmEoLiksIDAuMCkNCiAgICBSb3V0aW5nX0lOX04gPC0gbXV0YXRlKFJvdXRpbmdfSU5fTiwgSU5fTiA9IElOX04gKyBOX0lOX3RvXzEkSU5fTikNCg0KICAgICMgVG90YWwgSU4gKyBCTCBQDQogICAgUF9JTl9mcm9tIDwtIGZpbHRlcihSb3V0aW5nX0lOX1AsIElEID09IFVwcGVyW2ksMV0pICMgZnJvbQ0KICAgIFBfSU5fdG9fMSA8LSBmaWx0ZXIoUm91dGluZ19JTl9QLCBJRCA9PSBVcHBlcltpLDJdKSAlPiUNCiAgICAgIG11dGF0ZShJTl9QID0gUF9JTl9mcm9tJEFmd2VudGVsaW5nICogVXBwZXJbaSwzXSkgJT4lDQogICAgICBzZWxlY3QoSUQsIFllYXIsIE1vbnRoLCBJTl9QKQ0KICAgIFBfSU5fdG9fMSA8LSBsZWZ0X2pvaW4oQ2F0Y2htZW50X1RpbWUsIFBfSU5fdG9fMSwgYnkgPSBjKCJJRCIsICJZZWFyIiwgIk1vbnRoIikpICU+JQ0KICAgICAgcmVwbGFjZShpcy5uYSguKSwgMC4wKQ0KICAgIFJvdXRpbmdfSU5fUCA8LSBtdXRhdGUoUm91dGluZ19JTl9QLCBJTl9QID0gSU5fUCArIFBfSU5fdG9fMSRJTl9QKQ0KDQogICAgTl9EV19mcm9tIDwtIGZpbHRlcihSb3V0aW5nX0RXX04sIElEID09IFVwcGVyW2ksMV0pICMgZnJvbQ0KICAgIE5fRFdfdG9fMSA8LSBmaWx0ZXIoUm91dGluZ19EV19OLCBJRCA9PSBVcHBlcltpLDJdKSAlPiUNCiAgICAgIG11dGF0ZShEV19OID0gTl9EV19mcm9tJEFmd2VudGVsaW5nICogVXBwZXJbaSwzXSkgJT4lDQogICAgICBzZWxlY3QoSUQsIFllYXIsIE1vbnRoLCBEV19OKQ0KICAgIE5fRFdfdG9fMSA8LSBsZWZ0X2pvaW4oQ2F0Y2htZW50X1RpbWUsIE5fRFdfdG9fMSwgYnkgPSBjKCJJRCIsICJZZWFyIiwgIk1vbnRoIikpICU+JQ0KICAgICAgcmVwbGFjZShpcy5uYSguKSwgMC4wKQ0KICAgIFJvdXRpbmdfRFdfTiA8LSBtdXRhdGUoUm91dGluZ19EV19OLCBEV19OID0gRFdfTiArIE5fRFdfdG9fMSREV19OKQ0KDQogICAgTl9PUl9mcm9tIDwtIGZpbHRlcihSb3V0aW5nX09SX04sIElEID09IFVwcGVyW2ksMV0pICMgZnJvbQ0KICAgIE5fT1JfdG9fMSA8LSBmaWx0ZXIoUm91dGluZ19PUl9OLCBJRCA9PSBVcHBlcltpLDJdKSAlPiUNCiAgICAgIG11dGF0ZShPUl9OID0gTl9PUl9mcm9tJEFmd2VudGVsaW5nICogVXBwZXJbaSwzXSkgJT4lDQogICAgICBzZWxlY3QoSUQsIFllYXIsIE1vbnRoLCBPUl9OKQ0KICAgIE5fT1JfdG9fMSA8LSBsZWZ0X2pvaW4oQ2F0Y2htZW50X1RpbWUsIE5fT1JfdG9fMSwgYnkgPSBjKCJJRCIsICJZZWFyIiwgIk1vbnRoIikpICU+JQ0KICAgICAgcmVwbGFjZShpcy5uYSguKSwgMC4wKQ0KICAgIFJvdXRpbmdfT1JfTiA8LSBtdXRhdGUoUm91dGluZ19PUl9OLCBPUl9OID0gT1JfTiArIE5fT1JfdG9fMSRPUl9OKQ0KDQogICAgIyBUb3RhbCBPUiArIEJMIFANCiAgICBQX09SX2Zyb20gPC0gZmlsdGVyKFJvdXRpbmdfT1JfUCwgSUQgPT0gVXBwZXJbaSwxXSkgIyBmcm9tDQogICAgUF9PUl90b18xIDwtIGZpbHRlcihSb3V0aW5nX09SX1AsIElEID09IFVwcGVyW2ksMl0pICU+JQ0KICAgICAgbXV0YXRlKE9SX1AgPSBQX09SX2Zyb20kQWZ3ZW50ZWxpbmcgKiBVcHBlcltpLDNdKSAlPiUNCiAgICAgIHNlbGVjdChJRCwgWWVhciwgTW9udGgsIE9SX1ApDQogICAgUF9PUl90b18xIDwtIGxlZnRfam9pbihDYXRjaG1lbnRfVGltZSwgUF9PUl90b18xLCBieSA9IGMoIklEIiwgIlllYXIiLCAiTW9udGgiKSkgJT4lDQogICAgICByZXBsYWNlKGlzLm5hKC4pLCAwLjApDQogICAgUm91dGluZ19PUl9QIDwtIG11dGF0ZShSb3V0aW5nX09SX1AsIE9SX1AgPSBPUl9QICsgUF9PUl90b18xJE9SX1ApDQoNCiAgICBOX1JXWklfZnJvbSA8LSBmaWx0ZXIoUm91dGluZ19SV1pJX04sIElEID09IFVwcGVyW2ksMV0pICMgZnJvbQ0KICAgIE5fUldaSV90b18xIDwtIGZpbHRlcihSb3V0aW5nX1JXWklfTiwgSUQgPT0gVXBwZXJbaSwyXSkgJT4lDQogICAgICBtdXRhdGUoUldaSV9OID0gTl9SV1pJX2Zyb20kQWZ3ZW50ZWxpbmcgKiBVcHBlcltpLDNdKSAlPiUNCiAgICAgIHNlbGVjdChJRCwgWWVhciwgTW9udGgsIFJXWklfTikNCiAgICBOX1JXWklfdG9fMSA8LSBsZWZ0X2pvaW4oQ2F0Y2htZW50X1RpbWUsIE5fUldaSV90b18xLCBieSA9IGMoIklEIiwgIlllYXIiLCAiTW9udGgiKSkgJT4lDQogICAgICByZXBsYWNlKGlzLm5hKC4pLCAwLjApDQogICAgUm91dGluZ19SV1pJX04gPC0gbXV0YXRlKFJvdXRpbmdfUldaSV9OLCBSV1pJX04gPSBSV1pJX04gKyBOX1JXWklfdG9fMSRSV1pJX04pDQoNCiAgICAjIFRvdGFsIFJXWkkgKyBCTCBQDQogICAgUF9SV1pJX2Zyb20gPC0gZmlsdGVyKFJvdXRpbmdfUldaSV9QLCBJRCA9PSBVcHBlcltpLDFdKSAjIGZyb20NCiAgICBQX1JXWklfdG9fMSA8LSBmaWx0ZXIoUm91dGluZ19SV1pJX1AsIElEID09IFVwcGVyW2ksMl0pICU+JQ0KICAgICAgbXV0YXRlKFJXWklfUCA9IFBfUldaSV9mcm9tJEFmd2VudGVsaW5nICogVXBwZXJbaSwzXSkgJT4lDQogICAgICBzZWxlY3QoSUQsIFllYXIsIE1vbnRoLCBSV1pJX1ApDQogICAgUF9SV1pJX3RvXzEgPC0gbGVmdF9qb2luKENhdGNobWVudF9UaW1lLCBQX1JXWklfdG9fMSwgYnkgPSBjKCJJRCIsICJZZWFyIiwgIk1vbnRoIikpICU+JQ0KICAgICAgcmVwbGFjZShpcy5uYSguKSwgMC4wKQ0KICAgIFJvdXRpbmdfUldaSV9QIDwtIG11dGF0ZShSb3V0aW5nX1JXWklfUCwgUldaSV9QID0gUldaSV9QICsgUF9SV1pJX3RvXzEkUldaSV9QKQ0KDQogICAgIE5fQkxfZnJvbSA8LSBmaWx0ZXIoUm91dGluZ19CTF9OLCBJRCA9PSBVcHBlcltpLDFdKSAjIGZyb20NCiAgICBOX0JMX3RvXzEgPC0gZmlsdGVyKFJvdXRpbmdfQkxfTiwgSUQgPT0gVXBwZXJbaSwyXSkgJT4lDQogICAgICBtdXRhdGUoQkxfTiA9IE5fQkxfZnJvbSRBZndlbnRlbGluZyAqIFVwcGVyW2ksM10pICU+JQ0KICAgICAgc2VsZWN0KElELCBZZWFyLCBNb250aCwgQkxfTikNCiAgICBOX0JMX3RvXzEgPC0gbGVmdF9qb2luKENhdGNobWVudF9UaW1lLCBOX0JMX3RvXzEsIGJ5ID0gYygiSUQiLCAiWWVhciIsICJNb250aCIpKSAlPiUNCiAgICAgIHJlcGxhY2UoaXMubmEoLiksIDAuMCkNCiAgICBSb3V0aW5nX0JMX04gPC0gbXV0YXRlKFJvdXRpbmdfQkxfTiwgQkxfTiA9IEJMX04gKyBOX0JMX3RvXzEkQkxfTikNCg0KICAgICMgVG90YWwgQkwgKyBCTCBQDQogICAgUF9CTF9mcm9tIDwtIGZpbHRlcihSb3V0aW5nX0JMX1AsIElEID09IFVwcGVyW2ksMV0pICMgZnJvbQ0KICAgIFBfQkxfdG9fMSA8LSBmaWx0ZXIoUm91dGluZ19CTF9QLCBJRCA9PSBVcHBlcltpLDJdKSAlPiUNCiAgICAgIG11dGF0ZShCTF9QID0gUF9CTF9mcm9tJEFmd2VudGVsaW5nICogVXBwZXJbaSwzXSkgJT4lDQogICAgICBzZWxlY3QoSUQsIFllYXIsIE1vbnRoLCBCTF9QKQ0KICAgIFBfQkxfdG9fMSA8LSBsZWZ0X2pvaW4oQ2F0Y2htZW50X1RpbWUsIFBfQkxfdG9fMSwgYnkgPSBjKCJJRCIsICJZZWFyIiwgIk1vbnRoIikpICU+JQ0KICAgICAgcmVwbGFjZShpcy5uYSguKSwgMC4wKQ0KICAgIFJvdXRpbmdfQkxfUCA8LSBtdXRhdGUoUm91dGluZ19CTF9QLCBCTF9QID0gQkxfUCArIFBfQkxfdG9fMSRCTF9QKQ0KDQoNCiAgICBpZiAoIWlzLm5hKFVwcGVyW2ksNF0pKQ0KICAgIHsNCiAgICAgICMgU3RvbmUgTg0KICAgICAgTl9TdG9uZV90b18yIDwtIGZpbHRlcihSb3V0aW5nX1N0b25lX04sIElEID09IFVwcGVyW2ksNF0pICU+JQ0KICAgICAgICBtdXRhdGUoU3RvbmVfTiA9IE5fU3RvbmVfZnJvbSRBZndlbnRlbGluZyAqIFVwcGVyW2ksNV0pICU+JQ0KICAgICAgICBzZWxlY3QoSUQsIFllYXIsIE1vbnRoLCBTdG9uZV9OKQ0KICAgICAgTl9TdG9uZV90b18yIDwtIGxlZnRfam9pbihDYXRjaG1lbnRfVGltZSwgTl9TdG9uZV90b18yLCBieSA9IGMoIklEIiwgIlllYXIiLCAiTW9udGgiKSkgJT4lDQogICAgICAgIHJlcGxhY2UoaXMubmEoLiksIDAuMCkNCiAgICAgIFJvdXRpbmdfU3RvbmVfTiA8LSBtdXRhdGUoUm91dGluZ19TdG9uZV9OLCBTdG9uZV9OID0gU3RvbmVfTiArIE5fU3RvbmVfdG9fMiRTdG9uZV9OKQ0KDQogICAgICAjIEVSK0JMLCBODQogICAgICBOX0VSX3RvXzIgPC0gZmlsdGVyKFJvdXRpbmdfRVJfTiwgSUQgPT0gVXBwZXJbaSw0XSkgJT4lDQogICAgICAgIG11dGF0ZShFUl9OID0gTl9FUl9mcm9tJEFmd2VudGVsaW5nICogVXBwZXJbaSw1XSkgJT4lDQogICAgICAgIHNlbGVjdChJRCwgWWVhciwgTW9udGgsIEVSX04pDQogICAgICBOX0VSX3RvXzIgPC0gbGVmdF9qb2luKENhdGNobWVudF9UaW1lLCBOX0VSX3RvXzIsIGJ5ID0gYygiSUQiLCAiWWVhciIsICJNb250aCIpKSAlPiUNCiAgICAgICAgcmVwbGFjZShpcy5uYSguKSwgMC4wKQ0KICAgICAgUm91dGluZ19FUl9OIDwtIG11dGF0ZShSb3V0aW5nX0VSX04sIEVSX04gPSBFUl9OICsgTl9FUl90b18yJEVSX04pDQoNCiAgICAgICMgU3RvbmUgUA0KICAgICAgUF9TdG9uZV90b18yIDwtIGZpbHRlcihSb3V0aW5nX1N0b25lX1AsIElEID09IFVwcGVyW2ksNF0pICU+JQ0KICAgICAgICBtdXRhdGUoU3RvbmVfUCA9IFBfU3RvbmVfZnJvbSRBZndlbnRlbGluZyAqIFVwcGVyW2ksNV0pICU+JQ0KICAgICAgICBzZWxlY3QoSUQsIFllYXIsIE1vbnRoLCBTdG9uZV9QKQ0KICAgICAgUF9TdG9uZV90b18yIDwtIGxlZnRfam9pbihDYXRjaG1lbnRfVGltZSwgUF9TdG9uZV90b18yLCBieSA9IGMoIklEIiwgIlllYXIiLCAiTW9udGgiKSkgJT4lDQogICAgICAgIHJlcGxhY2UoaXMubmEoLiksIDAuMCkNCiAgICAgIFJvdXRpbmdfU3RvbmVfUCA8LSBtdXRhdGUoUm91dGluZ19TdG9uZV9QLCBTdG9uZV9QID0gU3RvbmVfUCArIFBfU3RvbmVfdG9fMiRTdG9uZV9QKQ0KICAgICAgIyBFUitCTCwgUA0KICAgICAgUF9FUl90b18yIDwtIGZpbHRlcihSb3V0aW5nX0VSX1AsIElEID09IFVwcGVyW2ksNF0pICU+JQ0KICAgICAgICBtdXRhdGUoRVJfUCA9IFBfRVJfZnJvbSRBZndlbnRlbGluZyAqIFVwcGVyW2ksNV0pICU+JQ0KICAgICAgICBzZWxlY3QoSUQsIFllYXIsIE1vbnRoLCBFUl9QKQ0KICAgICAgUF9FUl90b18yIDwtIGxlZnRfam9pbihDYXRjaG1lbnRfVGltZSwgUF9FUl90b18yLCBieSA9IGMoIklEIiwgIlllYXIiLCAiTW9udGgiKSkgJT4lDQogICAgICAgIHJlcGxhY2UoaXMubmEoLiksIDAuMCkNCiAgICAgIFJvdXRpbmdfRVJfUCA8LSBtdXRhdGUoUm91dGluZ19FUl9QLCBFUl9QID0gRVJfUCArIFBfRVJfdG9fMiRFUl9QKQ0KDQogICAgICAjIExPK0JMLCBODQogICAgICBOX0xPX3RvXzIgPC0gZmlsdGVyKFJvdXRpbmdfTE9fTiwgSUQgPT0gVXBwZXJbaSw0XSkgJT4lDQogICAgICAgIG11dGF0ZShMT19OID0gTl9MT19mcm9tJEFmd2VudGVsaW5nICogVXBwZXJbaSw1XSkgJT4lDQogICAgICAgIHNlbGVjdChJRCwgWWVhciwgTW9udGgsIExPX04pDQogICAgICBOX0xPX3RvXzIgPC0gbGVmdF9qb2luKENhdGNobWVudF9UaW1lLCBOX0xPX3RvXzIsIGJ5ID0gYygiSUQiLCAiWWVhciIsICJNb250aCIpKSAlPiUNCiAgICAgICAgcmVwbGFjZShpcy5uYSguKSwgMC4wKQ0KICAgICAgUm91dGluZ19MT19OIDwtIG11dGF0ZShSb3V0aW5nX0xPX04sIExPX04gPSBMT19OICsgTl9MT190b18yJExPX04pDQoNCiAgICAgICMgTE8rQkwsIFANCiAgICAgIFBfTE9fdG9fMiA8LSBmaWx0ZXIoUm91dGluZ19MT19QLCBJRCA9PSBVcHBlcltpLDRdKSAlPiUNCiAgICAgICAgbXV0YXRlKExPX1AgPSBQX0xPX2Zyb20kQWZ3ZW50ZWxpbmcgKiBVcHBlcltpLDVdKSAlPiUNCiAgICAgICAgc2VsZWN0KElELCBZZWFyLCBNb250aCwgTE9fUCkNCiAgICAgIFBfTE9fdG9fMiA8LSBsZWZ0X2pvaW4oQ2F0Y2htZW50X1RpbWUsIFBfTE9fdG9fMiwgYnkgPSBjKCJJRCIsICJZZWFyIiwgIk1vbnRoIikpICU+JQ0KICAgICAgICByZXBsYWNlKGlzLm5hKC4pLCAwLjApDQogICAgICBSb3V0aW5nX0xPX1AgPC0gbXV0YXRlKFJvdXRpbmdfTE9fUCwgTE9fUCA9IExPX1AgKyBQX0xPX3RvXzIkTE9fUCkNCg0KICAgICAgTl9JTl90b18yIDwtIGZpbHRlcihSb3V0aW5nX0lOX04sIElEID09IFVwcGVyW2ksNF0pICU+JQ0KICAgICAgICBtdXRhdGUoSU5fTiA9IE5fSU5fZnJvbSRBZndlbnRlbGluZyAqIFVwcGVyW2ksNV0pICU+JQ0KICAgICAgICBzZWxlY3QoSUQsIFllYXIsIE1vbnRoLCBJTl9OKQ0KICAgICAgTl9JTl90b18yIDwtIGxlZnRfam9pbihDYXRjaG1lbnRfVGltZSwgTl9JTl90b18yLCBieSA9IGMoIklEIiwgIlllYXIiLCAiTW9udGgiKSkgJT4lDQogICAgICAgIHJlcGxhY2UoaXMubmEoLiksIDAuMCkNCiAgICAgIFJvdXRpbmdfSU5fTiA8LSBtdXRhdGUoUm91dGluZ19JTl9OLCBJTl9OID0gSU5fTiArIE5fSU5fdG9fMiRJTl9OKQ0KDQogICAgICAjIElOK0JMLCBQDQogICAgICBQX0lOX3RvXzIgPC0gZmlsdGVyKFJvdXRpbmdfSU5fUCwgSUQgPT0gVXBwZXJbaSw0XSkgJT4lDQogICAgICAgIG11dGF0ZShJTl9QID0gUF9JTl9mcm9tJEFmd2VudGVsaW5nICogVXBwZXJbaSw1XSkgJT4lDQogICAgICAgIHNlbGVjdChJRCwgWWVhciwgTW9udGgsIElOX1ApDQogICAgICBQX0lOX3RvXzIgPC0gbGVmdF9qb2luKENhdGNobWVudF9UaW1lLCBQX0lOX3RvXzIsIGJ5ID0gYygiSUQiLCAiWWVhciIsICJNb250aCIpKSAlPiUNCiAgICAgICAgcmVwbGFjZShpcy5uYSguKSwgMC4wKQ0KICAgICAgUm91dGluZ19JTl9QIDwtIG11dGF0ZShSb3V0aW5nX0lOX1AsIElOX1AgPSBJTl9QICsgUF9JTl90b18yJElOX1ApDQoNCiAgICAgIE5fRFdfdG9fMiA8LSBmaWx0ZXIoUm91dGluZ19EV19OLCBJRCA9PSBVcHBlcltpLDRdKSAlPiUNCiAgICAgICAgbXV0YXRlKERXX04gPSBOX0RXX2Zyb20kQWZ3ZW50ZWxpbmcgKiBVcHBlcltpLDVdKSAlPiUNCiAgICAgICAgc2VsZWN0KElELCBZZWFyLCBNb250aCwgRFdfTikNCiAgICAgIE5fRFdfdG9fMiA8LSBsZWZ0X2pvaW4oQ2F0Y2htZW50X1RpbWUsIE5fRFdfdG9fMiwgYnkgPSBjKCJJRCIsICJZZWFyIiwgIk1vbnRoIikpICU+JQ0KICAgICAgICByZXBsYWNlKGlzLm5hKC4pLCAwLjApDQogICAgICBSb3V0aW5nX0RXX04gPC0gbXV0YXRlKFJvdXRpbmdfRFdfTiwgRFdfTiA9IERXX04gKyBOX0RXX3RvXzIkRFdfTikNCg0KICAgICAgTl9PUl90b18yIDwtIGZpbHRlcihSb3V0aW5nX09SX04sIElEID09IFVwcGVyW2ksNF0pICU+JQ0KICAgICAgICBtdXRhdGUoT1JfTiA9IE5fT1JfZnJvbSRBZndlbnRlbGluZyAqIFVwcGVyW2ksNV0pICU+JQ0KICAgICAgICBzZWxlY3QoSUQsIFllYXIsIE1vbnRoLCBPUl9OKQ0KICAgICAgTl9PUl90b18yIDwtIGxlZnRfam9pbihDYXRjaG1lbnRfVGltZSwgTl9PUl90b18yLCBieSA9IGMoIklEIiwgIlllYXIiLCAiTW9udGgiKSkgJT4lDQogICAgICAgIHJlcGxhY2UoaXMubmEoLiksIDAuMCkNCiAgICAgIFJvdXRpbmdfT1JfTiA8LSBtdXRhdGUoUm91dGluZ19PUl9OLCBPUl9OID0gT1JfTiArIE5fT1JfdG9fMiRPUl9OKQ0KDQogICAgICAjIE9SK0JMLCBQDQogICAgICBQX09SX3RvXzIgPC0gZmlsdGVyKFJvdXRpbmdfT1JfUCwgSUQgPT0gVXBwZXJbaSw0XSkgJT4lDQogICAgICAgIG11dGF0ZShPUl9QID0gUF9PUl9mcm9tJEFmd2VudGVsaW5nICogVXBwZXJbaSw1XSkgJT4lDQogICAgICAgIHNlbGVjdChJRCwgWWVhciwgTW9udGgsIE9SX1ApDQogICAgICBQX09SX3RvXzIgPC0gbGVmdF9qb2luKENhdGNobWVudF9UaW1lLCBQX09SX3RvXzIsIGJ5ID0gYygiSUQiLCAiWWVhciIsICJNb250aCIpKSAlPiUNCiAgICAgICAgcmVwbGFjZShpcy5uYSguKSwgMC4wKQ0KICAgICAgUm91dGluZ19PUl9QIDwtIG11dGF0ZShSb3V0aW5nX09SX1AsIE9SX1AgPSBPUl9QICsgUF9PUl90b18yJE9SX1ApDQoNCiAgICAgIE5fUldaSV90b18yIDwtIGZpbHRlcihSb3V0aW5nX1JXWklfTiwgSUQgPT0gVXBwZXJbaSw0XSkgJT4lDQogICAgICAgIG11dGF0ZShSV1pJX04gPSBOX1JXWklfZnJvbSRBZndlbnRlbGluZyAqIFVwcGVyW2ksNV0pICU+JQ0KICAgICAgICBzZWxlY3QoSUQsIFllYXIsIE1vbnRoLCBSV1pJX04pDQogICAgICBOX1JXWklfdG9fMiA8LSBsZWZ0X2pvaW4oQ2F0Y2htZW50X1RpbWUsIE5fUldaSV90b18yLCBieSA9IGMoIklEIiwgIlllYXIiLCAiTW9udGgiKSkgJT4lDQogICAgICAgIHJlcGxhY2UoaXMubmEoLiksIDAuMCkNCiAgICAgIFJvdXRpbmdfUldaSV9OIDwtIG11dGF0ZShSb3V0aW5nX1JXWklfTiwgUldaSV9OID0gUldaSV9OICsgTl9SV1pJX3RvXzIkUldaSV9OKQ0KDQogICAgICAjIFJXWkkrQkwsIFANCiAgICAgIFBfUldaSV90b18yIDwtIGZpbHRlcihSb3V0aW5nX1JXWklfUCwgSUQgPT0gVXBwZXJbaSw0XSkgJT4lDQogICAgICAgIG11dGF0ZShSV1pJX1AgPSBQX1JXWklfZnJvbSRBZndlbnRlbGluZyAqIFVwcGVyW2ksNV0pICU+JQ0KICAgICAgICBzZWxlY3QoSUQsIFllYXIsIE1vbnRoLCBSV1pJX1ApDQogICAgICBQX1JXWklfdG9fMiA8LSBsZWZ0X2pvaW4oQ2F0Y2htZW50X1RpbWUsIFBfUldaSV90b18yLCBieSA9IGMoIklEIiwgIlllYXIiLCAiTW9udGgiKSkgJT4lDQogICAgICAgIHJlcGxhY2UoaXMubmEoLiksIDAuMCkNCiAgICAgIFJvdXRpbmdfUldaSV9QIDwtIG11dGF0ZShSb3V0aW5nX1JXWklfUCwgUldaSV9QID0gUldaSV9QICsgUF9SV1pJX3RvXzIkUldaSV9QKQ0KDQogICAgICAgTl9CTF90b18yIDwtIGZpbHRlcihSb3V0aW5nX0JMX04sIElEID09IFVwcGVyW2ksNF0pICU+JQ0KICAgICAgICBtdXRhdGUoQkxfTiA9IE5fQkxfZnJvbSRBZndlbnRlbGluZyAqIFVwcGVyW2ksNV0pICU+JQ0KICAgICAgICBzZWxlY3QoSUQsIFllYXIsIE1vbnRoLCBCTF9OKQ0KICAgICAgTl9CTF90b18yIDwtIGxlZnRfam9pbihDYXRjaG1lbnRfVGltZSwgTl9CTF90b18yLCBieSA9IGMoIklEIiwgIlllYXIiLCAiTW9udGgiKSkgJT4lDQogICAgICAgIHJlcGxhY2UoaXMubmEoLiksIDAuMCkNCiAgICAgIFJvdXRpbmdfQkxfTiA8LSBtdXRhdGUoUm91dGluZ19CTF9OLCBCTF9OID0gQkxfTiArIE5fQkxfdG9fMiRCTF9OKQ0KDQogICAgICAjIEJMK0JMLCBQDQogICAgICBQX0JMX3RvXzIgPC0gZmlsdGVyKFJvdXRpbmdfQkxfUCwgSUQgPT0gVXBwZXJbaSw0XSkgJT4lDQogICAgICAgIG11dGF0ZShCTF9QID0gUF9CTF9mcm9tJEFmd2VudGVsaW5nICogVXBwZXJbaSw1XSkgJT4lDQogICAgICAgIHNlbGVjdChJRCwgWWVhciwgTW9udGgsIEJMX1ApDQogICAgICBQX0JMX3RvXzIgPC0gbGVmdF9qb2luKENhdGNobWVudF9UaW1lLCBQX0JMX3RvXzIsIGJ5ID0gYygiSUQiLCAiWWVhciIsICJNb250aCIpKSAlPiUNCiAgICAgICAgcmVwbGFjZShpcy5uYSguKSwgMC4wKQ0KICAgICAgUm91dGluZ19CTF9QIDwtIG11dGF0ZShSb3V0aW5nX0JMX1AsIEJMX1AgPSBCTF9QICsgUF9CTF90b18yJEJMX1ApDQoNCiAgICAgIGlmICghaXMubmEoVXBwZXJbaSw2XSkpDQogICAgICB7DQogICAgICAgICMgU3RvbmUgTg0KICAgICAgICBOX1N0b25lX3RvXzMgPC0gZmlsdGVyKFJvdXRpbmdfU3RvbmVfTiwgSUQgPT0gVXBwZXJbaSw2XSkgJT4lDQogICAgICAgICAgbXV0YXRlKFN0b25lX04gPSBOX1N0b25lX2Zyb20kQWZ3ZW50ZWxpbmcgKiBVcHBlcltpLDddKSAlPiUNCiAgICAgICAgICBzZWxlY3QoSUQsIFllYXIsIE1vbnRoLCBTdG9uZV9OKQ0KICAgICAgICBOX1N0b25lX3RvXzMgPC0gbGVmdF9qb2luKENhdGNobWVudF9UaW1lLCBOX1N0b25lX3RvXzMsIGJ5ID0gYygiSUQiLCAiWWVhciIsICJNb250aCIpKSAlPiUNCiAgICAgICAgICByZXBsYWNlKGlzLm5hKC4pLCAwLjApDQogICAgICAgIFJvdXRpbmdfU3RvbmVfTiA8LSBtdXRhdGUoUm91dGluZ19TdG9uZV9OLCBTdG9uZV9OID0gU3RvbmVfTiArIE5fU3RvbmVfdG9fMyRTdG9uZV9OKQ0KDQogICAgICAgICMgRVIrQkwsIE4NCiAgICAgICAgTl9FUl90b18zIDwtIGZpbHRlcihSb3V0aW5nX0VSX04sIElEID09IFVwcGVyW2ksNl0pICU+JQ0KICAgICAgICAgIG11dGF0ZShFUl9OID0gTl9FUl9mcm9tJEFmd2VudGVsaW5nICogVXBwZXJbaSw3XSkgJT4lDQogICAgICAgICAgc2VsZWN0KElELCBZZWFyLCBNb250aCwgRVJfTikNCiAgICAgICAgTl9FUl90b18zIDwtIGxlZnRfam9pbihDYXRjaG1lbnRfVGltZSwgTl9FUl90b18zLCBieSA9IGMoIklEIiwgIlllYXIiLCAiTW9udGgiKSkgJT4lDQogICAgICAgICAgcmVwbGFjZShpcy5uYSguKSwgMC4wKQ0KICAgICAgICBSb3V0aW5nX0VSX04gPC0gbXV0YXRlKFJvdXRpbmdfRVJfTiwgRVJfTiA9IEVSX04gKyBOX0VSX3RvXzMkRVJfTikNCg0KICAgICAgICAjIFN0b25lIFANCiAgICAgICAgUF9TdG9uZV90b18zIDwtIGZpbHRlcihSb3V0aW5nX1N0b25lX1AsIElEID09IFVwcGVyW2ksNl0pICU+JQ0KICAgICAgICAgIG11dGF0ZShTdG9uZV9QID0gUF9TdG9uZV9mcm9tJEFmd2VudGVsaW5nICogVXBwZXJbaSw3XSkgJT4lDQogICAgICAgICAgc2VsZWN0KElELCBZZWFyLCBNb250aCwgU3RvbmVfUCkNCiAgICAgICAgUF9TdG9uZV90b18zIDwtIGxlZnRfam9pbihDYXRjaG1lbnRfVGltZSwgUF9TdG9uZV90b18zLCBieSA9IGMoIklEIiwgIlllYXIiLCAiTW9udGgiKSkgJT4lDQogICAgICAgICAgcmVwbGFjZShpcy5uYSguKSwgMC4wKQ0KICAgICAgICBSb3V0aW5nX1N0b25lX1AgPC0gbXV0YXRlKFJvdXRpbmdfU3RvbmVfUCwgU3RvbmVfUCA9IFN0b25lX1AgKyBQX1N0b25lX3RvXzMkU3RvbmVfUCkNCiAgICAgICAgIyBFUitCTCwgUA0KICAgICAgICBQX0VSX3RvXzMgPC0gZmlsdGVyKFJvdXRpbmdfRVJfUCwgSUQgPT0gVXBwZXJbaSw2XSkgJT4lDQogICAgICAgICAgbXV0YXRlKEVSX1AgPSBQX0VSX2Zyb20kQWZ3ZW50ZWxpbmcgKiBVcHBlcltpLDddKSAlPiUNCiAgICAgICAgICBzZWxlY3QoSUQsIFllYXIsIE1vbnRoLCBFUl9QKQ0KICAgICAgICBQX0VSX3RvXzMgPC0gbGVmdF9qb2luKENhdGNobWVudF9UaW1lLCBQX0VSX3RvXzMsIGJ5ID0gYygiSUQiLCAiWWVhciIsICJNb250aCIpKSAlPiUNCiAgICAgICAgICByZXBsYWNlKGlzLm5hKC4pLCAwLjApDQogICAgICAgIFJvdXRpbmdfRVJfUCA8LSBtdXRhdGUoUm91dGluZ19FUl9QLCBFUl9QID0gRVJfUCArIFBfRVJfdG9fMyRFUl9QKQ0KDQogICAgICAgICMgTE8rQkwsIE4NCiAgICAgICAgTl9MT190b18zIDwtIGZpbHRlcihSb3V0aW5nX0xPX04sIElEID09IFVwcGVyW2ksNl0pICU+JQ0KICAgICAgICAgIG11dGF0ZShMT19OID0gTl9MT19mcm9tJEFmd2VudGVsaW5nICogVXBwZXJbaSw3XSkgJT4lDQogICAgICAgICAgc2VsZWN0KElELCBZZWFyLCBNb250aCwgTE9fTikNCiAgICAgICAgTl9MT190b18zIDwtIGxlZnRfam9pbihDYXRjaG1lbnRfVGltZSwgTl9MT190b18zLCBieSA9IGMoIklEIiwgIlllYXIiLCAiTW9udGgiKSkgJT4lDQogICAgICAgICAgcmVwbGFjZShpcy5uYSguKSwgMC4wKQ0KICAgICAgICBSb3V0aW5nX0xPX04gPC0gbXV0YXRlKFJvdXRpbmdfTE9fTiwgTE9fTiA9IExPX04gKyBOX0xPX3RvXzMkTE9fTikNCg0KICAgICAgICAjIExPK0JMLCBQDQogICAgICAgIFBfTE9fdG9fMyA8LSBmaWx0ZXIoUm91dGluZ19MT19QLCBJRCA9PSBVcHBlcltpLDZdKSAlPiUNCiAgICAgICAgICBtdXRhdGUoTE9fUCA9IFBfTE9fZnJvbSRBZndlbnRlbGluZyAqIFVwcGVyW2ksN10pICU+JQ0KICAgICAgICAgIHNlbGVjdChJRCwgWWVhciwgTW9udGgsIExPX1ApDQogICAgICAgIFBfTE9fdG9fMyA8LSBsZWZ0X2pvaW4oQ2F0Y2htZW50X1RpbWUsIFBfTE9fdG9fMywgYnkgPSBjKCJJRCIsICJZZWFyIiwgIk1vbnRoIikpICU+JQ0KICAgICAgICAgIHJlcGxhY2UoaXMubmEoLiksIDAuMCkNCiAgICAgICAgUm91dGluZ19MT19QIDwtIG11dGF0ZShSb3V0aW5nX0xPX1AsIExPX1AgPSBMT19QICsgUF9MT190b18zJExPX1ApDQoNCiAgICAgICAgIE5fSU5fdG9fMyA8LSBmaWx0ZXIoUm91dGluZ19JTl9OLCBJRCA9PSBVcHBlcltpLDZdKSAlPiUNCiAgICAgICAgICBtdXRhdGUoSU5fTiA9IE5fSU5fZnJvbSRBZndlbnRlbGluZyAqIFVwcGVyW2ksN10pICU+JQ0KICAgICAgICAgIHNlbGVjdChJRCwgWWVhciwgTW9udGgsIElOX04pDQogICAgICAgIE5fSU5fdG9fMyA8LSBsZWZ0X2pvaW4oQ2F0Y2htZW50X1RpbWUsIE5fSU5fdG9fMywgYnkgPSBjKCJJRCIsICJZZWFyIiwgIk1vbnRoIikpICU+JQ0KICAgICAgICAgIHJlcGxhY2UoaXMubmEoLiksIDAuMCkNCiAgICAgICAgUm91dGluZ19JTl9OIDwtIG11dGF0ZShSb3V0aW5nX0lOX04sIElOX04gPSBJTl9OICsgTl9JTl90b18zJElOX04pDQoNCiAgICAgICAgIyBJTitCTCwgUA0KICAgICAgICBQX0lOX3RvXzMgPC0gZmlsdGVyKFJvdXRpbmdfSU5fUCwgSUQgPT0gVXBwZXJbaSw2XSkgJT4lDQogICAgICAgICAgbXV0YXRlKElOX1AgPSBQX0lOX2Zyb20kQWZ3ZW50ZWxpbmcgKiBVcHBlcltpLDddKSAlPiUNCiAgICAgICAgICBzZWxlY3QoSUQsIFllYXIsIE1vbnRoLCBJTl9QKQ0KICAgICAgICBQX0lOX3RvXzMgPC0gbGVmdF9qb2luKENhdGNobWVudF9UaW1lLCBQX0lOX3RvXzMsIGJ5ID0gYygiSUQiLCAiWWVhciIsICJNb250aCIpKSAlPiUNCiAgICAgICAgICByZXBsYWNlKGlzLm5hKC4pLCAwLjApDQogICAgICAgIFJvdXRpbmdfSU5fUCA8LSBtdXRhdGUoUm91dGluZ19JTl9QLCBJTl9QID0gSU5fUCArIFBfSU5fdG9fMyRJTl9QKQ0KDQogICAgICAgIE5fRFdfdG9fMyA8LSBmaWx0ZXIoUm91dGluZ19EV19OLCBJRCA9PSBVcHBlcltpLDZdKSAlPiUNCiAgICAgICAgICBtdXRhdGUoRFdfTiA9IE5fRFdfZnJvbSRBZndlbnRlbGluZyAqIFVwcGVyW2ksN10pICU+JQ0KICAgICAgICAgIHNlbGVjdChJRCwgWWVhciwgTW9udGgsIERXX04pDQogICAgICAgIE5fRFdfdG9fMyA8LSBsZWZ0X2pvaW4oQ2F0Y2htZW50X1RpbWUsIE5fRFdfdG9fMywgYnkgPSBjKCJJRCIsICJZZWFyIiwgIk1vbnRoIikpICU+JQ0KICAgICAgICAgIHJlcGxhY2UoaXMubmEoLiksIDAuMCkNCiAgICAgICAgUm91dGluZ19EV19OIDwtIG11dGF0ZShSb3V0aW5nX0RXX04sIERXX04gPSBEV19OICsgTl9EV190b18zJERXX04pDQoNCiAgICAgICAgTl9PUl90b18zIDwtIGZpbHRlcihSb3V0aW5nX09SX04sIElEID09IFVwcGVyW2ksNl0pICU+JQ0KICAgICAgICAgIG11dGF0ZShPUl9OID0gTl9PUl9mcm9tJEFmd2VudGVsaW5nICogVXBwZXJbaSw3XSkgJT4lDQogICAgICAgICAgc2VsZWN0KElELCBZZWFyLCBNb250aCwgT1JfTikNCiAgICAgICAgTl9PUl90b18zIDwtIGxlZnRfam9pbihDYXRjaG1lbnRfVGltZSwgTl9PUl90b18zLCBieSA9IGMoIklEIiwgIlllYXIiLCAiTW9udGgiKSkgJT4lDQogICAgICAgICAgcmVwbGFjZShpcy5uYSguKSwgMC4wKQ0KICAgICAgICBSb3V0aW5nX09SX04gPC0gbXV0YXRlKFJvdXRpbmdfT1JfTiwgT1JfTiA9IE9SX04gKyBOX09SX3RvXzMkT1JfTikNCg0KICAgICAgICAjIE9SK0JMLCBQDQogICAgICAgIFBfT1JfdG9fMyA8LSBmaWx0ZXIoUm91dGluZ19PUl9QLCBJRCA9PSBVcHBlcltpLDZdKSAlPiUNCiAgICAgICAgICBtdXRhdGUoT1JfUCA9IFBfT1JfZnJvbSRBZndlbnRlbGluZyAqIFVwcGVyW2ksN10pICU+JQ0KICAgICAgICAgIHNlbGVjdChJRCwgWWVhciwgTW9udGgsIE9SX1ApDQogICAgICAgIFBfT1JfdG9fMyA8LSBsZWZ0X2pvaW4oQ2F0Y2htZW50X1RpbWUsIFBfT1JfdG9fMywgYnkgPSBjKCJJRCIsICJZZWFyIiwgIk1vbnRoIikpICU+JQ0KICAgICAgICAgIHJlcGxhY2UoaXMubmEoLiksIDAuMCkNCiAgICAgICAgUm91dGluZ19PUl9QIDwtIG11dGF0ZShSb3V0aW5nX09SX1AsIE9SX1AgPSBPUl9QICsgUF9PUl90b18zJE9SX1ApDQoNCiAgICAgICAgTl9SV1pJX3RvXzMgPC0gZmlsdGVyKFJvdXRpbmdfUldaSV9OLCBJRCA9PSBVcHBlcltpLDZdKSAlPiUNCiAgICAgICAgICBtdXRhdGUoUldaSV9OID0gTl9SV1pJX2Zyb20kQWZ3ZW50ZWxpbmcgKiBVcHBlcltpLDddKSAlPiUNCiAgICAgICAgICBzZWxlY3QoSUQsIFllYXIsIE1vbnRoLCBSV1pJX04pDQogICAgICAgIE5fUldaSV90b18zIDwtIGxlZnRfam9pbihDYXRjaG1lbnRfVGltZSwgTl9SV1pJX3RvXzMsIGJ5ID0gYygiSUQiLCAiWWVhciIsICJNb250aCIpKSAlPiUNCiAgICAgICAgICByZXBsYWNlKGlzLm5hKC4pLCAwLjApDQogICAgICAgIFJvdXRpbmdfUldaSV9OIDwtIG11dGF0ZShSb3V0aW5nX1JXWklfTiwgUldaSV9OID0gUldaSV9OICsgTl9SV1pJX3RvXzMkUldaSV9OKQ0KDQogICAgICAgICMgUldaSStCTCwgUA0KICAgICAgICBQX1JXWklfdG9fMyA8LSBmaWx0ZXIoUm91dGluZ19SV1pJX1AsIElEID09IFVwcGVyW2ksNl0pICU+JQ0KICAgICAgICAgIG11dGF0ZShSV1pJX1AgPSBQX1JXWklfZnJvbSRBZndlbnRlbGluZyAqIFVwcGVyW2ksN10pICU+JQ0KICAgICAgICAgIHNlbGVjdChJRCwgWWVhciwgTW9udGgsIFJXWklfUCkNCiAgICAgICAgUF9SV1pJX3RvXzMgPC0gbGVmdF9qb2luKENhdGNobWVudF9UaW1lLCBQX1JXWklfdG9fMywgYnkgPSBjKCJJRCIsICJZZWFyIiwgIk1vbnRoIikpICU+JQ0KICAgICAgICAgIHJlcGxhY2UoaXMubmEoLiksIDAuMCkNCiAgICAgICAgUm91dGluZ19SV1pJX1AgPC0gbXV0YXRlKFJvdXRpbmdfUldaSV9QLCBSV1pJX1AgPSBSV1pJX1AgKyBQX1JXWklfdG9fMyRSV1pJX1ApDQoNCiAgICAgICAgTl9CTF90b18zIDwtIGZpbHRlcihSb3V0aW5nX0JMX04sIElEID09IFVwcGVyW2ksNl0pICU+JQ0KICAgICAgICAgIG11dGF0ZShCTF9OID0gTl9CTF9mcm9tJEFmd2VudGVsaW5nICogVXBwZXJbaSw3XSkgJT4lDQogICAgICAgICAgc2VsZWN0KElELCBZZWFyLCBNb250aCwgQkxfTikNCiAgICAgICAgTl9CTF90b18zIDwtIGxlZnRfam9pbihDYXRjaG1lbnRfVGltZSwgTl9CTF90b18zLCBieSA9IGMoIklEIiwgIlllYXIiLCAiTW9udGgiKSkgJT4lDQogICAgICAgICAgcmVwbGFjZShpcy5uYSguKSwgMC4wKQ0KICAgICAgICBSb3V0aW5nX0JMX04gPC0gbXV0YXRlKFJvdXRpbmdfQkxfTiwgQkxfTiA9IEJMX04gKyBOX0JMX3RvXzMkQkxfTikNCg0KICAgICAgICAjIEJMK0JMLCBQDQogICAgICAgIFBfQkxfdG9fMyA8LSBmaWx0ZXIoUm91dGluZ19CTF9QLCBJRCA9PSBVcHBlcltpLDZdKSAlPiUNCiAgICAgICAgICBtdXRhdGUoQkxfUCA9IFBfQkxfZnJvbSRBZndlbnRlbGluZyAqIFVwcGVyW2ksN10pICU+JQ0KICAgICAgICAgIHNlbGVjdChJRCwgWWVhciwgTW9udGgsIEJMX1ApDQogICAgICAgIFBfQkxfdG9fMyA8LSBsZWZ0X2pvaW4oQ2F0Y2htZW50X1RpbWUsIFBfQkxfdG9fMywgYnkgPSBjKCJJRCIsICJZZWFyIiwgIk1vbnRoIikpICU+JQ0KICAgICAgICAgIHJlcGxhY2UoaXMubmEoLiksIDAuMCkNCiAgICAgICAgUm91dGluZ19CTF9QIDwtIG11dGF0ZShSb3V0aW5nX0JMX1AsIEJMX1AgPSBCTF9QICsgUF9CTF90b18zJEJMX1ApDQogICAgICB9DQogICAgfQ0KICB9DQogIFJvdXRpbmcgPC0gc2V0ZGlmZihSb3V0aW5nLCBVcHBlcikNCn0NCiMgQ2F0Y2htZW50IHJvdXRpbmcgcmVzdWx0cywgdG90YWwgcmV0ZW50aW9uIGFuZCBhZndlbnRlbGluZyBmcm9tIGVhY2ggY2F0Y2htZW50IChpbmNsdWRpbmcgcmVjZWl2ZWQgZnJvbSB1cHBlciBzdHJlYW1zKSwgc3RvcHBlZCBieSAzMDUgKHRvdGFsIGFtb3VudCBvZiBOL1AgZGlzY2hhcmdlZCBpbnRvIDMwNSBpcyBhbHJlYWR5IGNhbGN1bGF0ZWQpDQoNCndyaXRlLmNzdihSb3V0aW5nX1N0b25lX04sIGZpbGUgPSAiLi4vUmVzdWx0cy9Sb3V0aW5nX1N0b25lX04uY3N2Iiwgcm93Lm5hbWVzID0gRkFMU0UpDQp3cml0ZS5jc3YoUm91dGluZ19FUl9OLCBmaWxlID0gIi4uL1Jlc3VsdHMvUm91dGluZ19FUl9OLmNzdiIsIHJvdy5uYW1lcyA9IEZBTFNFKQ0Kd3JpdGUuY3N2KFJvdXRpbmdfU3RvbmVfUCwgZmlsZSA9ICIuLi9SZXN1bHRzL1JvdXRpbmdfU3RvbmVfUC5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkNCndyaXRlLmNzdihSb3V0aW5nX0VSX1AsIGZpbGUgPSAiLi4vUmVzdWx0cy9Sb3V0aW5nX0VSX1AuY3N2Iiwgcm93Lm5hbWVzID0gRkFMU0UpDQoNCndyaXRlLmNzdihSb3V0aW5nX0xPX04sIGZpbGUgPSAiLi4vUmVzdWx0cy9Sb3V0aW5nX0xPX04uY3N2Iiwgcm93Lm5hbWVzID0gRkFMU0UpDQp3cml0ZS5jc3YoUm91dGluZ19MT19QLCBmaWxlID0gIi4uL1Jlc3VsdHMvUm91dGluZ19MT19QLmNzdiIsIHJvdy5uYW1lcyA9IEZBTFNFKQ0KDQp3cml0ZS5jc3YoUm91dGluZ19JTl9OLCBmaWxlID0gIi4uL1Jlc3VsdHMvUm91dGluZ19JTl9OLmNzdiIsIHJvdy5uYW1lcyA9IEZBTFNFKQ0Kd3JpdGUuY3N2KFJvdXRpbmdfSU5fUCwgZmlsZSA9ICIuLi9SZXN1bHRzL1JvdXRpbmdfSU5fUC5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkNCg0Kd3JpdGUuY3N2KFJvdXRpbmdfRFdfTiwgZmlsZSA9ICIuLi9SZXN1bHRzL1JvdXRpbmdfRFdfTi5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkNCg0Kd3JpdGUuY3N2KFJvdXRpbmdfT1JfTiwgZmlsZSA9ICIuLi9SZXN1bHRzL1JvdXRpbmdfT1JfTi5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkNCndyaXRlLmNzdihSb3V0aW5nX09SX1AsIGZpbGUgPSAiLi4vUmVzdWx0cy9Sb3V0aW5nX09SX1AuY3N2Iiwgcm93Lm5hbWVzID0gRkFMU0UpDQoNCndyaXRlLmNzdihSb3V0aW5nX1JXWklfTiwgZmlsZSA9ICIuLi9SZXN1bHRzL1JvdXRpbmdfUldaSV9OLmNzdiIsIHJvdy5uYW1lcyA9IEZBTFNFKQ0Kd3JpdGUuY3N2KFJvdXRpbmdfUldaSV9QLCBmaWxlID0gIi4uL1Jlc3VsdHMvUm91dGluZ19SV1pJX1AuY3N2Iiwgcm93Lm5hbWVzID0gRkFMU0UpDQoNCndyaXRlLmNzdihSb3V0aW5nX0JMX04sIGZpbGUgPSAiLi4vUmVzdWx0cy9Sb3V0aW5nX0JMX04uY3N2Iiwgcm93Lm5hbWVzID0gRkFMU0UpDQp3cml0ZS5jc3YoUm91dGluZ19CTF9QLCBmaWxlID0gIi4uL1Jlc3VsdHMvUm91dGluZ19CTF9QLmNzdiIsIHJvdy5uYW1lcyA9IEZBTFNFKQ0KYGBgDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQojIHJvdXRpbmcgdG8gdGhlIG5vcnRoIHNlYQ0KIyBkaXJlY3QgaW50byB0aGUgbm9ydGggc2VhDQpgYGB7cn0NClJvdXRpbmdfU2VhX0RpcmVjdCA8LSBhcy5kYXRhLmZyYW1lKHJlYWRfZGVsaW0oVFhUX1RvX1NlYV9EaXJlY3QsIHNob3dfY29sX3R5cGVzID0gRkFMU0UpKSAlPiUNCiAgbXV0YXRlKERpc3RhbmNlID0gMC4wLCBQZXJjZW50ID0gMS4wKSAlPiUNCiAgcmVuYW1lKCJJbnRvIiA9ICJOb29yZHplZSIsICJOYW1lIiA9ICJOQUFNIikgJT4lDQogIHNlbGVjdChJRCwgTmFtZSwgSW50bywgRGlzdGFuY2UsIFBlcmNlbnQpDQpgYGANCiMgaW5kaXJlY3QgaW50byB0aGUgbm9ydGggc2VhLCBpbiBtZXRlcg0KYGBge3J9DQpSb3V0aW5nX1NlYV9JbkRpcmVjdCA8LSBhcy5kYXRhLmZyYW1lKHJlYWRfY3N2KENTVl9Ub19TZWFfSW5EaXJlY3QsIHNob3dfY29sX3R5cGVzID0gRkFMU0UpKSAlPiUNCiAgcGl2b3RfbG9uZ2VyKDU6MTIsIG5hbWVzX3RvID0gIkludG8iLCB2YWx1ZXNfdG8gPSAiRGlzdGFuY2UiKSAlPiUNCiAgbXV0YXRlKFBlcmNlbnQgPSBjYXNlX3doZW4oTkFBTSA9PSAiTWFhcyIgJiBJbnRvID09ICJIYXJpbmd2bGlldCIgfiAwLjI5LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOQUFNID09ICJNYWFzIiAmIEludG8gPT0gIk5pZXV3ZSBXYXRlcndlZyIgfiAwLjY4LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOQUFNID09ICJNYWFzIiAmIEludG8gPT0gIk5vb3JkemVla2FuYWFsIiB+IDAuMDMsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5BQU0gPT0gIlNjaGVsZGUiICYgSW50byA9PSAiT29zdGVyc2NoZWxkZSIgfiAwLjUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5BQU0gPT0gIlNjaGVsZGUiICYgSW50byA9PSAiV2VzdGVyc2NoZWxkZSIgfiAwLjUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5BQU0gPT0gIlJpam4gV2VzdCIgJiBJbnRvID09ICJIYXJpbmd2bGlldCIgfiAwLjI5LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOQUFNID09ICJSaWpuIFdlc3QiICYgSW50byA9PSAiTmlldXdlIFdhdGVyd2VnIiB+IDAuNjgsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5BQU0gPT0gIlJpam4gV2VzdCIgJiBJbnRvID09ICJOb29yZHplZWthbmFhbCIgfiAwLjAzLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOQUFNID09ICJSaWpuIE9vc3QiICYgSW50byA9PSAiSUpzc2VsbWVlciIgfiAxLjAsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5BQU0gPT0gIlJpam4gTm9vcmQiICYgSW50byA9PSAiV2FkZGVuemVlIFdlc3QiIH4gMS4wLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOQUFNID09ICJFZW1zIiAmIEludG8gPT0gIldhZGRlbnplZSBPb3N0IiB+IDEuMCkpICU+JQ0KICBkcm9wX25hKCkgJT4lDQogIHJlbmFtZSgiTmFtZSIgPSAiTkFBTSIpICU+JQ0KICBzZWxlY3QoSUQsIE5hbWUsIEludG8sIERpc3RhbmNlLCBQZXJjZW50KQ0KYGBgDQojIEFsbA0KYGBge3J9DQpSb3V0aW5nX1NlYSA8LSBiaW5kX3Jvd3MoUm91dGluZ19TZWFfRGlyZWN0LCBSb3V0aW5nX1NlYV9JbkRpcmVjdCkgJT4lDQogIG11dGF0ZShSZWxlYXNlX0ZyYV9OID0gZXhwKC0gS19OICogRGlzdGFuY2UgLyAoVl9zdHJlYW0gKiAyNCAqIDYwICogNjApKSwNCiAgICAgICAgIFJlbGVhc2VfRnJhX1AgPSBleHAoLSBLX1AgKiBEaXN0YW5jZSAvIChWX3N0cmVhbSAqIDI0ICogNjAgKiA2MCkpLA0KICAgICAgICAgUmV0X0V4dHJhID0gY2FzZV93aGVuKEludG8gPT0gIklKc3NlbG1lZXIiIH4gMC41LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEludG8gJWluJSBjKCJIYXJpbmd2bGlldCIsICJXZXN0ZXJzY2hlbGRlIiwgIk9vc3RlcnNjaGVsZGUiKSB+IDAuOSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUlVFIH4gMS4wKSkgJT4lICMgcHJvcG9ydGlvbmFsIHRvIHRyYXZlbCB0aW1lLCBleHRyYSByZXRlbnRpb24gZm9yIElqc2VsbWVlciBlbiBFc3R1YXJpYQ0KICBtdXRhdGUoUmVsZWFzZV9GcmFfUCA9IFJlbGVhc2VfRnJhX1AgKiBSZXRfRXh0cmEpICU+JQ0KICBtdXRhdGUoUmVsZWFzZV9GcmFfUCA9IGlmZWxzZShSZWxlYXNlX0ZyYV9QIDwgMC4xLCAwLjEsIFJlbGVhc2VfRnJhX1ApLCBSZWxlYXNlX0ZyYV9OID0gaWZlbHNlKFJlbGVhc2VfRnJhX04gPCAwLjEsIDAuMSwgUmVsZWFzZV9GcmFfTikpICAjIGFma2FwcGVuIHpvZGF0IHJldGVudGllIG5vb2l0IGdyb3RlciBpcyBkYW4gOTAlDQpgYGANCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyBQcmVwYXJlIGRhdGEgZm9yIHJpdmVyIHJvdXRpbmcNCiMgU3RvbmUgTg0KYGBge3J9DQpOb29yZHplZV9TdG9uZV9OIDwtIHNlbGVjdChSb3V0aW5nX1N0b25lX04sIElELCBZZWFyLCBNb250aCwgQWZ3ZW50ZWxpbmcpICU+JQ0KICBpbm5lcl9qb2luKFJvdXRpbmdfU2VhLCBieSA9ICJJRCIpDQoNCk5fV2VuTyA8LSBmaWx0ZXIoTm9vcmR6ZWVfU3RvbmVfTiwgSW50byA9PSAiV2VzdGVyLSBlbiBPb3N0ZXJzY2hlbGRlIikNCk5fVyA8LSBtdXRhdGUoTl9XZW5PLCBBZndlbnRlbGluZyA9IDAuNyAqIEFmd2VudGVsaW5nLCBJbnRvID0gIldlc3RlcnNjaGVsZGUiKQ0KTl9PIDwtIG11dGF0ZShOX1dlbk8sIEFmd2VudGVsaW5nID0gMC4zICogQWZ3ZW50ZWxpbmcsIEludG8gPSAiT29zdGVyc2NoZWxkZSIpDQoNCk5vb3JkemVlX1N0b25lX04gPC0gTm9vcmR6ZWVfU3RvbmVfTiAlPiUNCiAgZmlsdGVyKCFJbnRvICVpbiUgYygiV2VzdGVyLSBlbiBPb3N0ZXJzY2hlbGRlIiwgIioqRHVpdHNsYW5kIikpICU+JQ0KICBiaW5kX3Jvd3MoTl9XLCBOX08pDQpOb29yZHplZV9TdG9uZV9OIDwtIE5vb3JkemVlX1N0b25lX04gJT4lDQogIG11dGF0ZShTdG9uZV9OID0gUGVyY2VudCAqIFJlbGVhc2VfRnJhX04gKiBBZndlbnRlbGluZykgJT4lDQogIGdyb3VwX2J5KFllYXIsIE1vbnRoLCBJbnRvKSAlPiUNCiAgc3VtbWFyaXNlKFN0b25lX04gPSBzdW0oU3RvbmVfTiwgbmEucm0gPSBUUlVFKSwgLmdyb3VwcyA9ICJkcm9wIikNCg0Kd3JpdGUuY3N2KE5vb3JkemVlX1N0b25lX04sIGZpbGUgPSAiLi4vUmVzdWx0cy9Ob29yZHplZV9TdG9uZV9OLmNzdiIsIHJvdy5uYW1lcyA9IEZBTFNFKQ0KYGBgDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgU3RvbmUgUA0KYGBge3J9DQpOb29yZHplZV9TdG9uZV9QIDwtIHNlbGVjdChSb3V0aW5nX1N0b25lX1AsIElELCBZZWFyLCBNb250aCwgQWZ3ZW50ZWxpbmcpICU+JQ0KICBpbm5lcl9qb2luKFJvdXRpbmdfU2VhLCBieSA9ICJJRCIpDQoNClBfV2VuTyA8LSBmaWx0ZXIoTm9vcmR6ZWVfU3RvbmVfUCwgSW50byA9PSAiV2VzdGVyLSBlbiBPb3N0ZXJzY2hlbGRlIikNClBfVyA8LSBtdXRhdGUoUF9XZW5PLCBBZndlbnRlbGluZyA9IDAuNyAqIEFmd2VudGVsaW5nLCBJbnRvID0gIldlc3RlcnNjaGVsZGUiKQ0KUF9PIDwtIG11dGF0ZShQX1dlbk8sIEFmd2VudGVsaW5nID0gMC4zICogQWZ3ZW50ZWxpbmcsIEludG8gPSAiT29zdGVyc2NoZWxkZSIpDQoNCk5vb3JkemVlX1N0b25lX1AgPC0gTm9vcmR6ZWVfU3RvbmVfUCAlPiUNCiAgZmlsdGVyKCFJbnRvICVpbiUgYygiV2VzdGVyLSBlbiBPb3N0ZXJzY2hlbGRlIiwgIioqRHVpdHNsYW5kIikpICU+JQ0KICBiaW5kX3Jvd3MoUF9XLCBQX08pDQpOb29yZHplZV9TdG9uZV9QIDwtIE5vb3JkemVlX1N0b25lX1AgJT4lDQogIG11dGF0ZShTdG9uZV9QID0gUGVyY2VudCAqIFJlbGVhc2VfRnJhX1AgKiBBZndlbnRlbGluZykgJT4lDQogIGdyb3VwX2J5KFllYXIsIE1vbnRoLCBJbnRvKSAlPiUNCiAgc3VtbWFyaXNlKFN0b25lX1AgPSBzdW0oU3RvbmVfUCwgbmEucm0gPSBUUlVFKSwgLmdyb3VwcyA9ICJkcm9wIikNCg0Kd3JpdGUuY3N2KE5vb3JkemVlX1N0b25lX1AsIGZpbGUgPSAiLi4vUmVzdWx0cy9Ob29yZHplZV9TdG9uZV9QLmNzdiIsIHJvdy5uYW1lcyA9IEZBTFNFKQ0KYGBgDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgRVIgTg0KYGBge3J9DQpOb29yZHplZV9FUl9OIDwtIHNlbGVjdChSb3V0aW5nX0VSX04sIElELCBZZWFyLCBNb250aCwgQWZ3ZW50ZWxpbmcpICU+JQ0KICBpbm5lcl9qb2luKFJvdXRpbmdfU2VhLCBieSA9ICJJRCIpDQoNCk5fV2VuTyA8LSBmaWx0ZXIoTm9vcmR6ZWVfRVJfTiwgSW50byA9PSAiV2VzdGVyLSBlbiBPb3N0ZXJzY2hlbGRlIikNCk5fVyA8LSBtdXRhdGUoTl9XZW5PLCBBZndlbnRlbGluZyA9IDAuNyAqIEFmd2VudGVsaW5nLCBJbnRvID0gIldlc3RlcnNjaGVsZGUiKQ0KTl9PIDwtIG11dGF0ZShOX1dlbk8sIEFmd2VudGVsaW5nID0gMC4zICogQWZ3ZW50ZWxpbmcsIEludG8gPSAiT29zdGVyc2NoZWxkZSIpDQoNCk5vb3JkemVlX0VSX04gPC0gTm9vcmR6ZWVfRVJfTiAlPiUNCiAgZmlsdGVyKCFJbnRvICVpbiUgYygiV2VzdGVyLSBlbiBPb3N0ZXJzY2hlbGRlIiwgIioqRHVpdHNsYW5kIikpICU+JQ0KICBiaW5kX3Jvd3MoTl9XLCBOX08pDQpOb29yZHplZV9FUl9OIDwtIE5vb3JkemVlX0VSX04gJT4lDQogIG11dGF0ZShFUl9OID0gUGVyY2VudCAqIFJlbGVhc2VfRnJhX04gKiBBZndlbnRlbGluZykgJT4lDQogIGdyb3VwX2J5KFllYXIsIE1vbnRoLCBJbnRvKSAlPiUNCiAgc3VtbWFyaXNlKEVSX04gPSBzdW0oRVJfTiwgbmEucm0gPSBUUlVFKSwgLmdyb3VwcyA9ICJkcm9wIikNCg0Kd3JpdGUuY3N2KE5vb3JkemVlX0VSX04sIGZpbGUgPSAiLi4vUmVzdWx0cy9Ob29yZHplZV9FUl9OLmNzdiIsIHJvdy5uYW1lcyA9IEZBTFNFKQ0KYGBgDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgRVIgUA0KYGBge3J9DQpOb29yZHplZV9FUl9QIDwtIHNlbGVjdChSb3V0aW5nX0VSX1AsIElELCBZZWFyLCBNb250aCwgQWZ3ZW50ZWxpbmcpICU+JQ0KICBpbm5lcl9qb2luKFJvdXRpbmdfU2VhLCBieSA9ICJJRCIpDQoNClBfV2VuTyA8LSBmaWx0ZXIoTm9vcmR6ZWVfRVJfUCwgSW50byA9PSAiV2VzdGVyLSBlbiBPb3N0ZXJzY2hlbGRlIikNClBfVyA8LSBtdXRhdGUoUF9XZW5PLCBBZndlbnRlbGluZyA9IDAuNyAqIEFmd2VudGVsaW5nLCBJbnRvID0gIldlc3RlcnNjaGVsZGUiKQ0KUF9PIDwtIG11dGF0ZShQX1dlbk8sIEFmd2VudGVsaW5nID0gMC4zICogQWZ3ZW50ZWxpbmcsIEludG8gPSAiT29zdGVyc2NoZWxkZSIpDQoNCk5vb3JkemVlX0VSX1AgPC0gTm9vcmR6ZWVfRVJfUCAlPiUNCiAgZmlsdGVyKCFJbnRvICVpbiUgYygiV2VzdGVyLSBlbiBPb3N0ZXJzY2hlbGRlIiwgIioqRHVpdHNsYW5kIikpICU+JQ0KICBiaW5kX3Jvd3MoUF9XLCBQX08pDQpOb29yZHplZV9FUl9QIDwtIE5vb3JkemVlX0VSX1AgJT4lDQogIG11dGF0ZShFUl9QID0gUGVyY2VudCAqIFJlbGVhc2VfRnJhX1AgKiBBZndlbnRlbGluZykgJT4lDQogIGdyb3VwX2J5KFllYXIsIE1vbnRoLCBJbnRvKSAlPiUNCiAgc3VtbWFyaXNlKEVSX1AgPSBzdW0oRVJfUCwgbmEucm0gPSBUUlVFKSwgLmdyb3VwcyA9ICJkcm9wIikNCg0Kd3JpdGUuY3N2KE5vb3JkemVlX0VSX1AsIGZpbGUgPSAiLi4vUmVzdWx0cy9Ob29yZHplZV9FUl9QLmNzdiIsIHJvdy5uYW1lcyA9IEZBTFNFKQ0KYGBgDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgSU4gTg0KYGBge3J9DQpOb29yZHplZV9JTl9OIDwtIHNlbGVjdChSb3V0aW5nX0lOX04sIElELCBZZWFyLCBNb250aCwgQWZ3ZW50ZWxpbmcpICU+JQ0KICBpbm5lcl9qb2luKFJvdXRpbmdfU2VhLCBieSA9ICJJRCIpDQoNCk5fV2VuTyA8LSBmaWx0ZXIoTm9vcmR6ZWVfSU5fTiwgSW50byA9PSAiV2VzdGVyLSBlbiBPb3N0ZXJzY2hlbGRlIikNCk5fVyA8LSBtdXRhdGUoTl9XZW5PLCBBZndlbnRlbGluZyA9IDAuNyAqIEFmd2VudGVsaW5nLCBJbnRvID0gIldlc3RlcnNjaGVsZGUiKQ0KTl9PIDwtIG11dGF0ZShOX1dlbk8sIEFmd2VudGVsaW5nID0gMC4zICogQWZ3ZW50ZWxpbmcsIEludG8gPSAiT29zdGVyc2NoZWxkZSIpDQoNCk5vb3JkemVlX0lOX04gPC0gTm9vcmR6ZWVfSU5fTiAlPiUNCiAgZmlsdGVyKCFJbnRvICVpbiUgYygiV2VzdGVyLSBlbiBPb3N0ZXJzY2hlbGRlIiwgIioqRHVpdHNsYW5kIikpICU+JQ0KICBiaW5kX3Jvd3MoTl9XLCBOX08pDQpOb29yZHplZV9JTl9OIDwtIE5vb3JkemVlX0lOX04gJT4lDQogIG11dGF0ZShJTl9OID0gUGVyY2VudCAqIFJlbGVhc2VfRnJhX04gKiBBZndlbnRlbGluZykgJT4lDQogIGdyb3VwX2J5KFllYXIsIE1vbnRoLCBJbnRvKSAlPiUNCiAgc3VtbWFyaXNlKElOX04gPSBzdW0oSU5fTiwgbmEucm0gPSBUUlVFKSwgLmdyb3VwcyA9ICJkcm9wIikNCg0Kd3JpdGUuY3N2KE5vb3JkemVlX0lOX04sIGZpbGUgPSAiLi4vUmVzdWx0cy9Ob29yZHplZV9JTl9OLmNzdiIsIHJvdy5uYW1lcyA9IEZBTFNFKQ0KYGBgDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgSU4gUA0KYGBge3J9DQpOb29yZHplZV9JTl9QIDwtIHNlbGVjdChSb3V0aW5nX0lOX1AsIElELCBZZWFyLCBNb250aCwgQWZ3ZW50ZWxpbmcpICU+JQ0KICBpbm5lcl9qb2luKFJvdXRpbmdfU2VhLCBieSA9ICJJRCIpDQoNClBfV2VuTyA8LSBmaWx0ZXIoTm9vcmR6ZWVfSU5fUCwgSW50byA9PSAiV2VzdGVyLSBlbiBPb3N0ZXJzY2hlbGRlIikNClBfVyA8LSBtdXRhdGUoUF9XZW5PLCBBZndlbnRlbGluZyA9IDAuNyAqIEFmd2VudGVsaW5nLCBJbnRvID0gIldlc3RlcnNjaGVsZGUiKQ0KUF9PIDwtIG11dGF0ZShQX1dlbk8sIEFmd2VudGVsaW5nID0gMC4zICogQWZ3ZW50ZWxpbmcsIEludG8gPSAiT29zdGVyc2NoZWxkZSIpDQoNCk5vb3JkemVlX0lOX1AgPC0gTm9vcmR6ZWVfSU5fUCAlPiUNCiAgZmlsdGVyKCFJbnRvICVpbiUgYygiV2VzdGVyLSBlbiBPb3N0ZXJzY2hlbGRlIiwgIioqRHVpdHNsYW5kIikpICU+JQ0KICBiaW5kX3Jvd3MoUF9XLCBQX08pDQpOb29yZHplZV9JTl9QIDwtIE5vb3JkemVlX0lOX1AgJT4lDQogIG11dGF0ZShJTl9QID0gUGVyY2VudCAqIFJlbGVhc2VfRnJhX1AgKiBBZndlbnRlbGluZykgJT4lDQogIGdyb3VwX2J5KFllYXIsIE1vbnRoLCBJbnRvKSAlPiUNCiAgc3VtbWFyaXNlKElOX1AgPSBzdW0oSU5fUCwgbmEucm0gPSBUUlVFKSwgLmdyb3VwcyA9ICJkcm9wIikNCg0Kd3JpdGUuY3N2KE5vb3JkemVlX0lOX1AsIGZpbGUgPSAiLi4vUmVzdWx0cy9Ob29yZHplZV9JTl9QLmNzdiIsIHJvdy5uYW1lcyA9IEZBTFNFKQ0KYGBgDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgTE8gTg0KYGBge3J9DQpOb29yZHplZV9MT19OIDwtIHNlbGVjdChSb3V0aW5nX0xPX04sIElELCBZZWFyLCBNb250aCwgQWZ3ZW50ZWxpbmcpICU+JQ0KICBpbm5lcl9qb2luKFJvdXRpbmdfU2VhLCBieSA9ICJJRCIpDQoNCk5fV2VuTyA8LSBmaWx0ZXIoTm9vcmR6ZWVfTE9fTiwgSW50byA9PSAiV2VzdGVyLSBlbiBPb3N0ZXJzY2hlbGRlIikNCk5fVyA8LSBtdXRhdGUoTl9XZW5PLCBBZndlbnRlbGluZyA9IDAuNyAqIEFmd2VudGVsaW5nLCBJbnRvID0gIldlc3RlcnNjaGVsZGUiKQ0KTl9PIDwtIG11dGF0ZShOX1dlbk8sIEFmd2VudGVsaW5nID0gMC4zICogQWZ3ZW50ZWxpbmcsIEludG8gPSAiT29zdGVyc2NoZWxkZSIpDQoNCk5vb3JkemVlX0xPX04gPC0gTm9vcmR6ZWVfTE9fTiAlPiUNCiAgZmlsdGVyKCFJbnRvICVpbiUgYygiV2VzdGVyLSBlbiBPb3N0ZXJzY2hlbGRlIiwgIioqRHVpdHNsYW5kIikpICU+JQ0KICBiaW5kX3Jvd3MoTl9XLCBOX08pDQpOb29yZHplZV9MT19OIDwtIE5vb3JkemVlX0xPX04gJT4lDQogIG11dGF0ZShMT19OID0gUGVyY2VudCAqIFJlbGVhc2VfRnJhX04gKiBBZndlbnRlbGluZykgJT4lDQogIGdyb3VwX2J5KFllYXIsIE1vbnRoLCBJbnRvKSAlPiUNCiAgc3VtbWFyaXNlKExPX04gPSBzdW0oTE9fTiwgbmEucm0gPSBUUlVFKSwgLmdyb3VwcyA9ICJkcm9wIikNCg0Kd3JpdGUuY3N2KE5vb3JkemVlX0xPX04sIGZpbGUgPSAiLi4vUmVzdWx0cy9Ob29yZHplZV9MT19OLmNzdiIsIHJvdy5uYW1lcyA9IEZBTFNFKQ0KYGBgDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgTE8gUA0KYGBge3J9DQpOb29yZHplZV9MT19QIDwtIHNlbGVjdChSb3V0aW5nX0xPX1AsIElELCBZZWFyLCBNb250aCwgQWZ3ZW50ZWxpbmcpICU+JQ0KICBpbm5lcl9qb2luKFJvdXRpbmdfU2VhLCBieSA9ICJJRCIpDQoNClBfV2VuTyA8LSBmaWx0ZXIoTm9vcmR6ZWVfTE9fUCwgSW50byA9PSAiV2VzdGVyLSBlbiBPb3N0ZXJzY2hlbGRlIikNClBfVyA8LSBtdXRhdGUoUF9XZW5PLCBBZndlbnRlbGluZyA9IDAuNyAqIEFmd2VudGVsaW5nLCBJbnRvID0gIldlc3RlcnNjaGVsZGUiKQ0KUF9PIDwtIG11dGF0ZShQX1dlbk8sIEFmd2VudGVsaW5nID0gMC4zICogQWZ3ZW50ZWxpbmcsIEludG8gPSAiT29zdGVyc2NoZWxkZSIpDQoNCk5vb3JkemVlX0xPX1AgPC0gTm9vcmR6ZWVfTE9fUCAlPiUNCiAgZmlsdGVyKCFJbnRvICVpbiUgYygiV2VzdGVyLSBlbiBPb3N0ZXJzY2hlbGRlIiwgIioqRHVpdHNsYW5kIikpICU+JQ0KICBiaW5kX3Jvd3MoUF9XLCBQX08pDQpOb29yZHplZV9MT19QIDwtIE5vb3JkemVlX0xPX1AgJT4lDQogIG11dGF0ZShMT19QID0gUGVyY2VudCAqIFJlbGVhc2VfRnJhX1AgKiBBZndlbnRlbGluZykgJT4lDQogIGdyb3VwX2J5KFllYXIsIE1vbnRoLCBJbnRvKSAlPiUNCiAgc3VtbWFyaXNlKExPX1AgPSBzdW0oTE9fUCwgbmEucm0gPSBUUlVFKSwgLmdyb3VwcyA9ICJkcm9wIikNCg0Kd3JpdGUuY3N2KE5vb3JkemVlX0xPX1AsIGZpbGUgPSAiLi4vUmVzdWx0cy9Ob29yZHplZV9MT19QLmNzdiIsIHJvdy5uYW1lcyA9IEZBTFNFKQ0KYGBgDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgT1IgTg0KYGBge3J9DQpOb29yZHplZV9PUl9OIDwtIHNlbGVjdChSb3V0aW5nX09SX04sIElELCBZZWFyLCBNb250aCwgQWZ3ZW50ZWxpbmcpICU+JQ0KICBpbm5lcl9qb2luKFJvdXRpbmdfU2VhLCBieSA9ICJJRCIpDQoNCk5fV2VuTyA8LSBmaWx0ZXIoTm9vcmR6ZWVfT1JfTiwgSW50byA9PSAiV2VzdGVyLSBlbiBPb3N0ZXJzY2hlbGRlIikNCk5fVyA8LSBtdXRhdGUoTl9XZW5PLCBBZndlbnRlbGluZyA9IDAuNyAqIEFmd2VudGVsaW5nLCBJbnRvID0gIldlc3RlcnNjaGVsZGUiKQ0KTl9PIDwtIG11dGF0ZShOX1dlbk8sIEFmd2VudGVsaW5nID0gMC4zICogQWZ3ZW50ZWxpbmcsIEludG8gPSAiT29zdGVyc2NoZWxkZSIpDQoNCk5vb3JkemVlX09SX04gPC0gTm9vcmR6ZWVfT1JfTiAlPiUNCiAgZmlsdGVyKCFJbnRvICVpbiUgYygiV2VzdGVyLSBlbiBPb3N0ZXJzY2hlbGRlIiwgIioqRHVpdHNsYW5kIikpICU+JQ0KICBiaW5kX3Jvd3MoTl9XLCBOX08pDQpOb29yZHplZV9PUl9OIDwtIE5vb3JkemVlX09SX04gJT4lDQogIG11dGF0ZShPUl9OID0gUGVyY2VudCAqIFJlbGVhc2VfRnJhX04gKiBBZndlbnRlbGluZykgJT4lDQogIGdyb3VwX2J5KFllYXIsIE1vbnRoLCBJbnRvKSAlPiUNCiAgc3VtbWFyaXNlKE9SX04gPSBzdW0oT1JfTiwgbmEucm0gPSBUUlVFKSwgLmdyb3VwcyA9ICJkcm9wIikNCg0Kd3JpdGUuY3N2KE5vb3JkemVlX09SX04sIGZpbGUgPSAiLi4vUmVzdWx0cy9Ob29yZHplZV9PUl9OLmNzdiIsIHJvdy5uYW1lcyA9IEZBTFNFKQ0KYGBgDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgT1IgUA0KYGBge3J9DQpOb29yZHplZV9PUl9QIDwtIHNlbGVjdChSb3V0aW5nX09SX1AsIElELCBZZWFyLCBNb250aCwgQWZ3ZW50ZWxpbmcpICU+JQ0KICBpbm5lcl9qb2luKFJvdXRpbmdfU2VhLCBieSA9ICJJRCIpDQoNClBfV2VuTyA8LSBmaWx0ZXIoTm9vcmR6ZWVfT1JfUCwgSW50byA9PSAiV2VzdGVyLSBlbiBPb3N0ZXJzY2hlbGRlIikNClBfVyA8LSBtdXRhdGUoUF9XZW5PLCBBZndlbnRlbGluZyA9IDAuNyAqIEFmd2VudGVsaW5nLCBJbnRvID0gIldlc3RlcnNjaGVsZGUiKQ0KUF9PIDwtIG11dGF0ZShQX1dlbk8sIEFmd2VudGVsaW5nID0gMC4zICogQWZ3ZW50ZWxpbmcsIEludG8gPSAiT29zdGVyc2NoZWxkZSIpDQoNCk5vb3JkemVlX09SX1AgPC0gTm9vcmR6ZWVfT1JfUCAlPiUNCiAgZmlsdGVyKCFJbnRvICVpbiUgYygiV2VzdGVyLSBlbiBPb3N0ZXJzY2hlbGRlIiwgIioqRHVpdHNsYW5kIikpICU+JQ0KICBiaW5kX3Jvd3MoUF9XLCBQX08pDQpOb29yZHplZV9PUl9QIDwtIE5vb3JkemVlX09SX1AgJT4lDQogIG11dGF0ZShPUl9QID0gUGVyY2VudCAqIFJlbGVhc2VfRnJhX1AgKiBBZndlbnRlbGluZykgJT4lDQogIGdyb3VwX2J5KFllYXIsIE1vbnRoLCBJbnRvKSAlPiUNCiAgc3VtbWFyaXNlKE9SX1AgPSBzdW0oT1JfUCwgbmEucm0gPSBUUlVFKSwgLmdyb3VwcyA9ICJkcm9wIikNCg0Kd3JpdGUuY3N2KE5vb3JkemVlX09SX1AsIGZpbGUgPSAiLi4vUmVzdWx0cy9Ob29yZHplZV9PUl9QLmNzdiIsIHJvdy5uYW1lcyA9IEZBTFNFKQ0KYGBgDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgRFcgTg0KYGBge3J9DQpOb29yZHplZV9EV19OIDwtIHNlbGVjdChSb3V0aW5nX0RXX04sIElELCBZZWFyLCBNb250aCwgQWZ3ZW50ZWxpbmcpICU+JQ0KICBpbm5lcl9qb2luKFJvdXRpbmdfU2VhLCBieSA9ICJJRCIpDQoNCk5fV2VuTyA8LSBmaWx0ZXIoTm9vcmR6ZWVfRFdfTiwgSW50byA9PSAiV2VzdGVyLSBlbiBPb3N0ZXJzY2hlbGRlIikNCk5fVyA8LSBtdXRhdGUoTl9XZW5PLCBBZndlbnRlbGluZyA9IDAuNyAqIEFmd2VudGVsaW5nLCBJbnRvID0gIldlc3RlcnNjaGVsZGUiKQ0KTl9PIDwtIG11dGF0ZShOX1dlbk8sIEFmd2VudGVsaW5nID0gMC4zICogQWZ3ZW50ZWxpbmcsIEludG8gPSAiT29zdGVyc2NoZWxkZSIpDQoNCk5vb3JkemVlX0RXX04gPC0gTm9vcmR6ZWVfRFdfTiAlPiUNCiAgZmlsdGVyKCFJbnRvICVpbiUgYygiV2VzdGVyLSBlbiBPb3N0ZXJzY2hlbGRlIiwgIioqRHVpdHNsYW5kIikpICU+JQ0KICBiaW5kX3Jvd3MoTl9XLCBOX08pDQpOb29yZHplZV9EV19OIDwtIE5vb3JkemVlX0RXX04gJT4lDQogIG11dGF0ZShEV19OID0gUGVyY2VudCAqIFJlbGVhc2VfRnJhX04gKiBBZndlbnRlbGluZykgJT4lDQogIGdyb3VwX2J5KFllYXIsIE1vbnRoLCBJbnRvKSAlPiUNCiAgc3VtbWFyaXNlKERXX04gPSBzdW0oRFdfTiwgbmEucm0gPSBUUlVFKSwgLmdyb3VwcyA9ICJkcm9wIikNCg0Kd3JpdGUuY3N2KE5vb3JkemVlX0RXX04sIGZpbGUgPSAiLi4vUmVzdWx0cy9Ob29yZHplZV9EV19OLmNzdiIsIHJvdy5uYW1lcyA9IEZBTFNFKQ0KYGBgDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgUldaSSBODQpgYGB7cn0NCk5vb3JkemVlX1JXWklfTiA8LSBzZWxlY3QoUm91dGluZ19SV1pJX04sIElELCBZZWFyLCBNb250aCwgQWZ3ZW50ZWxpbmcpICU+JQ0KICBpbm5lcl9qb2luKFJvdXRpbmdfU2VhLCBieSA9ICJJRCIpDQoNCk5fV2VuTyA8LSBmaWx0ZXIoTm9vcmR6ZWVfUldaSV9OLCBJbnRvID09ICJXZXN0ZXItIGVuIE9vc3RlcnNjaGVsZGUiKQ0KTl9XIDwtIG11dGF0ZShOX1dlbk8sIEFmd2VudGVsaW5nID0gMC43ICogQWZ3ZW50ZWxpbmcsIEludG8gPSAiV2VzdGVyc2NoZWxkZSIpDQpOX08gPC0gbXV0YXRlKE5fV2VuTywgQWZ3ZW50ZWxpbmcgPSAwLjMgKiBBZndlbnRlbGluZywgSW50byA9ICJPb3N0ZXJzY2hlbGRlIikNCg0KTm9vcmR6ZWVfUldaSV9OIDwtIE5vb3JkemVlX1JXWklfTiAlPiUNCiAgZmlsdGVyKCFJbnRvICVpbiUgYygiV2VzdGVyLSBlbiBPb3N0ZXJzY2hlbGRlIiwgIioqRHVpdHNsYW5kIikpICU+JQ0KICBiaW5kX3Jvd3MoTl9XLCBOX08pDQpOb29yZHplZV9SV1pJX04gPC0gTm9vcmR6ZWVfUldaSV9OICU+JQ0KICBtdXRhdGUoUldaSV9OID0gUGVyY2VudCAqIFJlbGVhc2VfRnJhX04gKiBBZndlbnRlbGluZykgJT4lDQogIGdyb3VwX2J5KFllYXIsIE1vbnRoLCBJbnRvKSAlPiUNCiAgc3VtbWFyaXNlKFJXWklfTiA9IHN1bShSV1pJX04sIG5hLnJtID0gVFJVRSksIC5ncm91cHMgPSAiZHJvcCIpDQoNCndyaXRlLmNzdihOb29yZHplZV9SV1pJX04sIGZpbGUgPSAiLi4vUmVzdWx0cy9Ob29yZHplZV9SV1pJX04uY3N2Iiwgcm93Lm5hbWVzID0gRkFMU0UpDQpgYGANCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyBSV1pJIFANCmBgYHtyfQ0KTm9vcmR6ZWVfUldaSV9QIDwtIHNlbGVjdChSb3V0aW5nX1JXWklfUCwgSUQsIFllYXIsIE1vbnRoLCBBZndlbnRlbGluZykgJT4lDQogIGlubmVyX2pvaW4oUm91dGluZ19TZWEsIGJ5ID0gIklEIikNCg0KUF9XZW5PIDwtIGZpbHRlcihOb29yZHplZV9SV1pJX1AsIEludG8gPT0gIldlc3Rlci0gZW4gT29zdGVyc2NoZWxkZSIpDQpQX1cgPC0gbXV0YXRlKFBfV2VuTywgQWZ3ZW50ZWxpbmcgPSAwLjcgKiBBZndlbnRlbGluZywgSW50byA9ICJXZXN0ZXJzY2hlbGRlIikNClBfTyA8LSBtdXRhdGUoUF9XZW5PLCBBZndlbnRlbGluZyA9IDAuMyAqIEFmd2VudGVsaW5nLCBJbnRvID0gIk9vc3RlcnNjaGVsZGUiKQ0KDQpOb29yZHplZV9SV1pJX1AgPC0gTm9vcmR6ZWVfUldaSV9QICU+JQ0KICBmaWx0ZXIoIUludG8gJWluJSBjKCJXZXN0ZXItIGVuIE9vc3RlcnNjaGVsZGUiLCAiKipEdWl0c2xhbmQiKSkgJT4lDQogIGJpbmRfcm93cyhQX1csIFBfTykNCk5vb3JkemVlX1JXWklfUCA8LSBOb29yZHplZV9SV1pJX1AgJT4lDQogIG11dGF0ZShSV1pJX1AgPSBQZXJjZW50ICogUmVsZWFzZV9GcmFfUCAqIEFmd2VudGVsaW5nKSAlPiUNCiAgZ3JvdXBfYnkoWWVhciwgTW9udGgsIEludG8pICU+JQ0KICBzdW1tYXJpc2UoUldaSV9QID0gc3VtKFJXWklfUCwgbmEucm0gPSBUUlVFKSwgLmdyb3VwcyA9ICJkcm9wIikNCg0Kd3JpdGUuY3N2KE5vb3JkemVlX1JXWklfUCwgZmlsZSA9ICIuLi9SZXN1bHRzL05vb3JkemVlX1JXWklfUC5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkNCmBgYA0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIEJMIE4NCmBgYHtyfQ0KTm9vcmR6ZWVfQkxfTiA8LSBzZWxlY3QoUm91dGluZ19CTF9OLCBJRCwgWWVhciwgTW9udGgsIEFmd2VudGVsaW5nKSAlPiUNCiAgaW5uZXJfam9pbihSb3V0aW5nX1NlYSwgYnkgPSAiSUQiKQ0KDQpOX1dlbk8gPC0gZmlsdGVyKE5vb3JkemVlX0JMX04sIEludG8gPT0gIldlc3Rlci0gZW4gT29zdGVyc2NoZWxkZSIpDQpOX1cgPC0gbXV0YXRlKE5fV2VuTywgQWZ3ZW50ZWxpbmcgPSAwLjcgKiBBZndlbnRlbGluZywgSW50byA9ICJXZXN0ZXJzY2hlbGRlIikNCk5fTyA8LSBtdXRhdGUoTl9XZW5PLCBBZndlbnRlbGluZyA9IDAuMyAqIEFmd2VudGVsaW5nLCBJbnRvID0gIk9vc3RlcnNjaGVsZGUiKQ0KDQpOb29yZHplZV9CTF9OIDwtIE5vb3JkemVlX0JMX04gJT4lDQogIGZpbHRlcighSW50byAlaW4lIGMoIldlc3Rlci0gZW4gT29zdGVyc2NoZWxkZSIsICIqKkR1aXRzbGFuZCIpKSAlPiUNCiAgYmluZF9yb3dzKE5fVywgTl9PKQ0KTm9vcmR6ZWVfQkxfTiA8LSBOb29yZHplZV9CTF9OICU+JQ0KICBtdXRhdGUoQkxfTiA9IFBlcmNlbnQgKiBSZWxlYXNlX0ZyYV9OICogQWZ3ZW50ZWxpbmcpICU+JQ0KICBncm91cF9ieShZZWFyLCBNb250aCwgSW50bykgJT4lDQogIHN1bW1hcmlzZShCTF9OID0gc3VtKEJMX04sIG5hLnJtID0gVFJVRSksIC5ncm91cHMgPSAiZHJvcCIpDQoNCndyaXRlLmNzdihOb29yZHplZV9CTF9OLCBmaWxlID0gIi4uL1Jlc3VsdHMvTm9vcmR6ZWVfQkxfTi5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkNCmBgYA0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIEJMIFANCmBgYHtyfQ0KTm9vcmR6ZWVfQkxfUCA8LSBzZWxlY3QoUm91dGluZ19CTF9QLCBJRCwgWWVhciwgTW9udGgsIEFmd2VudGVsaW5nKSAlPiUNCiAgaW5uZXJfam9pbihSb3V0aW5nX1NlYSwgYnkgPSAiSUQiKQ0KDQpQX1dlbk8gPC0gZmlsdGVyKE5vb3JkemVlX0JMX1AsIEludG8gPT0gIldlc3Rlci0gZW4gT29zdGVyc2NoZWxkZSIpDQpQX1cgPC0gbXV0YXRlKFBfV2VuTywgQWZ3ZW50ZWxpbmcgPSAwLjcgKiBBZndlbnRlbGluZywgSW50byA9ICJXZXN0ZXJzY2hlbGRlIikNClBfTyA8LSBtdXRhdGUoUF9XZW5PLCBBZndlbnRlbGluZyA9IDAuMyAqIEFmd2VudGVsaW5nLCBJbnRvID0gIk9vc3RlcnNjaGVsZGUiKQ0KDQpOb29yZHplZV9CTF9QIDwtIE5vb3JkemVlX0JMX1AgJT4lDQogIGZpbHRlcighSW50byAlaW4lIGMoIldlc3Rlci0gZW4gT29zdGVyc2NoZWxkZSIsICIqKkR1aXRzbGFuZCIpKSAlPiUNCiAgYmluZF9yb3dzKFBfVywgUF9PKQ0KTm9vcmR6ZWVfQkxfUCA8LSBOb29yZHplZV9CTF9QICU+JQ0KICBtdXRhdGUoQkxfUCA9IFBlcmNlbnQgKiBSZWxlYXNlX0ZyYV9QICogQWZ3ZW50ZWxpbmcpICU+JQ0KICBncm91cF9ieShZZWFyLCBNb250aCwgSW50bykgJT4lDQogIHN1bW1hcmlzZShCTF9QID0gc3VtKEJMX1AsIG5hLnJtID0gVFJVRSksIC5ncm91cHMgPSAiZHJvcCIpDQoNCndyaXRlLmNzdihOb29yZHplZV9CTF9QLCBmaWxlID0gIi4uL1Jlc3VsdHMvTm9vcmR6ZWVfQkxfUC5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkNCmBgYA0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIElubGV0IGJpZyByaXZlcnMNCmBgYHtyfQ0KTm9vcmR6ZWVfSW5sZXRfTiA8LSBzZWxlY3QoSW5sZXRfTl9Nb250aGx5LCBJRCwgWWVhciwgTW9udGgsIEFmd2VudGVsaW5nID0gSW5sZXRfTikgJT4lDQogIGlubmVyX2pvaW4oUm91dGluZ19TZWEsIGJ5ID0gIklEIikgJT4lDQogIG11dGF0ZShJbmxldF9OID0gUGVyY2VudCAqIFJlbGVhc2VfRnJhX04gKiBBZndlbnRlbGluZykgJT4lDQogIGdyb3VwX2J5KFllYXIsIE1vbnRoLCBJbnRvKSAlPiUNCiAgc3VtbWFyaXNlKElubGV0X04gPSBzdW0oSW5sZXRfTiwgbmEucm0gPSBUUlVFKSwgLmdyb3VwcyA9ICJkcm9wIikNCg0Kd3JpdGUuY3N2KE5vb3JkemVlX0lubGV0X04sIGZpbGUgPSAiLi4vUmVzdWx0cy9Ob29yZHplZV9CTF9CaWdSaXZlcnNfTi5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkNCmBgYA0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIElubGV0IFAsIGJpZyByaXZlcnMNCmBgYHtyfQ0KTm9vcmR6ZWVfSW5sZXRfUCA8LSBzZWxlY3QoSW5sZXRfUF9Nb250aGx5LCBJRCwgWWVhciwgTW9udGgsIEFmd2VudGVsaW5nID0gSW5sZXRfUCkgJT4lDQogIGlubmVyX2pvaW4oUm91dGluZ19TZWEsIGJ5ID0gIklEIikgJT4lDQogIG11dGF0ZShJbmxldF9QID0gUGVyY2VudCAqIFJlbGVhc2VfRnJhX1AgKiBBZndlbnRlbGluZykgJT4lDQogIGdyb3VwX2J5KFllYXIsIE1vbnRoLCBJbnRvKSAlPiUNCiAgc3VtbWFyaXNlKElubGV0X1AgPSBzdW0oSW5sZXRfUCwgbmEucm0gPSBUUlVFKSwgLmdyb3VwcyA9ICJkcm9wIikNCg0Kd3JpdGUuY3N2KE5vb3JkemVlX0lubGV0X1AsIGZpbGUgPSAiLi4vUmVzdWx0cy9Ob29yZHplZV9CTF9CaWdSaXZlcnNfUC5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkNCmBgYA0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0K